This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch 
feature/CAMEL-24564-devconsole-openapi-catalog
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 4ba2803df33ac3f9b5ed5ada8ea94aa6a5a8ddd6
Author: Claus Ibsen <[email protected]>
AuthorDate: Sat Aug 29 14:08:34 2026 +0200

    CAMEL-24564: camel-tooling-model - Generate a static OpenAPI spec for all 
dev consoles and publish it in the camel-catalog
    
    Extract the OpenAPI path/operation-building logic out of ApiDevConsole into 
a
    new shared DevConsoleOpenApiHelper in camel-tooling-model, operating on the
    existing DevConsoleModel/DevConsoleOptionModel typed beans (adding the
    readOnly flag from CAMEL-24514 to that model and to JsonMapper's
    generate/serialize methods, which it was previously missing).
    
    ApiDevConsole now builds its live spec by parsing each console's catalog
    schema via JsonMapper.generateDevConsoleModel() and delegating to the shared
    helper, instead of hand-rolling JSON navigation - behavior-preserving.
    
    PrepareCatalogMojo's executeDevConsoles() already parses every console's
    catalog JSON into a DevConsoleModel while aggregating them into
    camel-catalog; it now also builds a single consolidated
    dev-consoles-openapi.json from those same models via the shared helper, with
    zero additional parsing and no CamelContext dependency. Exposed via a new
    CamelCatalog.devConsolesOpenApiSpec() method, mirroring the existing
    mainJsonSchema()/jbangJsonSchema() raw-resource pattern.
    
    Co-Authored-By: Claude Sonnet 5 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../apache/camel/catalog/dev-consoles-openapi.json | 2489 ++++++++++++++++++++
 .../org/apache/camel/catalog/CamelCatalog.java     |    5 +
 .../apache/camel/catalog/DefaultCamelCatalog.java  |    5 +
 .../org/apache/camel/catalog/CamelCatalogTest.java |   25 +
 core/camel-console/pom.xml                         |    5 +
 .../apache/camel/impl/console/ApiDevConsole.java   |  183 +-
 .../camel/tooling/model/DevConsoleModel.java       |    9 +
 .../tooling/model/DevConsoleOpenApiHelper.java     |  160 ++
 .../org/apache/camel/tooling/model/JsonMapper.java |    2 +
 .../tooling/model/DevConsoleOpenApiHelperTest.java |  126 +
 .../camel/maven/packaging/PrepareCatalogMojo.java  |   12 +
 11 files changed, 2858 insertions(+), 163 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles-openapi.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles-openapi.json
new file mode 100644
index 000000000000..6846a963fad3
--- /dev/null
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles-openapi.json
@@ -0,0 +1,2489 @@
+{
+       "openapi": "3.0.3",
+       "info": {
+               "title": "Camel Dev Console API",
+               "version": "4.23.0-SNAPSHOT"
+       },
+       "paths": {
+               "\/q\/dev\/activity": {
+                       "get": {
+                               "summary": "Camel Activity",
+                               "description": "Recent completed exchange 
activity",
+                               "operationId": "activity",
+                               "responses": {
+                                       "200": {
+                                               "description": "Camel Activity 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/api": {
+                       "get": {
+                               "summary": "API",
+                               "description": "OpenAPI specification for the 
dev console API",
+                               "operationId": "api",
+                               "responses": {
+                                       "200": {
+                                               "description": "API output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/aws-secrets": {
+                       "get": {
+                               "summary": "AWS Secrets",
+                               "description": "AWS Secrets Manager",
+                               "operationId": "aws-secrets",
+                               "responses": {
+                                       "200": {
+                                               "description": "AWS Secrets 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/aws2-s3": {
+                       "get": {
+                               "summary": "AWS S3",
+                               "description": "AWS S3 Consumer",
+                               "operationId": "aws2-s3",
+                               "responses": {
+                                       "200": {
+                                               "description": "AWS S3 output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/azure-secrets": {
+                       "get": {
+                               "summary": "Azure Key Vault Secrets",
+                               "description": "Azure Key Vault Secret Manager",
+                               "operationId": "azure-secrets",
+                               "responses": {
+                                       "200": {
+                                               "description": "Azure Key Vault 
Secrets output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/bean": {
+                       "get": {
+                               "summary": "Bean",
+                               "description": "Displays Java beans from the 
registry",
+                               "operationId": "bean",
+                               "parameters": [
+                                       {
+                                               "name": "filter",
+                                               "in": "query",
+                                               "description": "Filters the 
beans matching by name",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "string"
+                                               }
+                                       },
+                                       {
+                                               "name": "internal",
+                                               "in": "query",
+                                               "description": "Whether to 
include internal Camel beans",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": true
+                                               }
+                                       },
+                                       {
+                                               "name": "nulls",
+                                               "in": "query",
+                                               "description": "Whether to 
include null values",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": true
+                                               }
+                                       },
+                                       {
+                                               "name": "properties",
+                                               "in": "query",
+                                               "description": "Whether to 
include bean properties",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": true
+                                               }
+                                       }
+                               ],
+                               "responses": {
+                                       "200": {
+                                               "description": "Bean output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/bean-model": {
+                       "get": {
+                               "summary": "Bean Model",
+                               "description": "Displays beans from the DSL 
model",
+                               "operationId": "bean-model",
+                               "parameters": [
+                                       {
+                                               "name": "filter",
+                                               "in": "query",
+                                               "description": "Filters the 
beans matching by name",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "string"
+                                               }
+                                       },
+                                       {
+                                               "name": "nulls",
+                                               "in": "query",
+                                               "description": "Whether to 
include null values",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": true
+                                               }
+                                       },
+                                       {
+                                               "name": "properties",
+                                               "in": "query",
+                                               "description": "Whether to 
include bean properties",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": true
+                                               }
+                                       }
+                               ],
+                               "responses": {
+                                       "200": {
+                                               "description": "Bean Model 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/blocked": {
+                       "get": {
+                               "summary": "Blocked Exchanges",
+                               "description": "Display blocked exchanges",
+                               "operationId": "blocked",
+                               "responses": {
+                                       "200": {
+                                               "description": "Blocked 
Exchanges output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/browse": {
+                       "get": {
+                               "summary": "Browse",
+                               "description": "Browse pending messages on 
Camel components",
+                               "operationId": "browse",
+                               "parameters": [
+                                       {
+                                               "name": "bodyMaxChars",
+                                               "in": "query",
+                                               "description": "Maximum size of 
the message body to include in the dump",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "integer",
+                                                       "default": 32768
+                                               }
+                                       },
+                                       {
+                                               "name": "dump",
+                                               "in": "query",
+                                               "description": "Whether to 
include message dumps",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": true
+                                               }
+                                       },
+                                       {
+                                               "name": "filter",
+                                               "in": "query",
+                                               "description": "Filters the 
endpoints matching by route id, endpoint url",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "string"
+                                               }
+                                       },
+                                       {
+                                               "name": "freshSize",
+                                               "in": "query",
+                                               "description": "Whether to 
calculate fresh queue size (can cause performance overhead)",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": false
+                                               }
+                                       },
+                                       {
+                                               "name": "includeBody",
+                                               "in": "query",
+                                               "description": "Whether to 
include message body in dumps",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": true
+                                               }
+                                       },
+                                       {
+                                               "name": "limit",
+                                               "in": "query",
+                                               "description": "Limits the 
number of entries per endpoint",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "integer",
+                                                       "default": 100
+                                               }
+                                       },
+                                       {
+                                               "name": "tail",
+                                               "in": "query",
+                                               "description": "To receive N 
last messages from the tail",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "integer"
+                                               }
+                                       }
+                               ],
+                               "responses": {
+                                       "200": {
+                                               "description": "Browse output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/circuit-breaker": {
+                       "get": {
+                               "summary": "Circuit Breaker",
+                               "description": "Display circuit breaker 
information",
+                               "operationId": "circuit-breaker",
+                               "responses": {
+                                       "200": {
+                                               "description": "Circuit Breaker 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/consumer": {
+                       "get": {
+                               "summary": "Consumers",
+                               "description": "Display information about Camel 
consumers",
+                               "operationId": "consumer",
+                               "responses": {
+                                       "200": {
+                                               "description": "Consumers 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/context": {
+                       "get": {
+                               "summary": "CamelContext",
+                               "description": "Overall information about the 
CamelContext",
+                               "operationId": "context",
+                               "responses": {
+                                       "200": {
+                                               "description": "CamelContext 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/datasource": {
+                       "get": {
+                               "summary": "DataSource",
+                               "description": "Displays DataSource connection 
pool metrics",
+                               "operationId": "datasource",
+                               "responses": {
+                                       "200": {
+                                               "description": "DataSource 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/debug": {
+                       "post": {
+                               "summary": "Debug",
+                               "description": "Camel route debugger",
+                               "operationId": "debug",
+                               "requestBody": {
+                                       "content": {
+                                               "application\/json": {
+                                                       "schema": {
+                                                               "type": 
"object",
+                                                               "properties": {
+                                                                       
"breakpoint": {
+                                                                               
"type": "string",
+                                                                               
"description": "The breakpoint node id"
+                                                                       },
+                                                                       
"codeLimit": {
+                                                                               
"type": "integer",
+                                                                               
"default": 5,
+                                                                               
"description": "Number of source code lines around the breakpoint to include"
+                                                                       },
+                                                                       
"command": {
+                                                                               
"type": "string",
+                                                                               
"description": "Action command to execute on the debugger"
+                                                                       },
+                                                                       
"history": {
+                                                                               
"type": "boolean",
+                                                                               
"default": true,
+                                                                               
"description": "Whether to include message history"
+                                                                       },
+                                                                       
"position": {
+                                                                               
"type": "integer",
+                                                                               
"description": "The position to step to"
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               },
+                               "responses": {
+                                       "200": {
+                                               "description": "Debug output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/endpoint": {
+                       "get": {
+                               "summary": "Endpoints",
+                               "description": "Endpoint Registry information",
+                               "operationId": "endpoint",
+                               "responses": {
+                                       "200": {
+                                               "description": "Endpoints 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/errors": {
+                       "get": {
+                               "summary": "Error Registry",
+                               "description": "Display captured routing 
errors",
+                               "operationId": "errors",
+                               "parameters": [
+                                       {
+                                               "name": "ago",
+                                               "in": "query",
+                                               "description": "Filter by time 
window as duration string (e.g. 60s, 5m, 1h). Only entries within this window 
are included.",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "string"
+                                               }
+                                       },
+                                       {
+                                               "name": "exception",
+                                               "in": "query",
+                                               "description": "Filter by 
exception type (case-insensitive substring match)",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "string"
+                                               }
+                                       },
+                                       {
+                                               "name": "handled",
+                                               "in": "query",
+                                               "description": "Filter by 
handled status",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean"
+                                               }
+                                       },
+                                       {
+                                               "name": "limit",
+                                               "in": "query",
+                                               "description": "Limits the 
number of entries displayed",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "integer"
+                                               }
+                                       },
+                                       {
+                                               "name": "routeId",
+                                               "in": "query",
+                                               "description": "Filter by route 
id",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "string"
+                                               }
+                                       },
+                                       {
+                                               "name": "stackTrace",
+                                               "in": "query",
+                                               "description": "Whether to 
include stack traces",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": false
+                                               }
+                                       }
+                               ],
+                               "responses": {
+                                       "200": {
+                                               "description": "Error Registry 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/eval-language": {
+                       "post": {
+                               "summary": "Evaluate Language",
+                               "description": "Evaluate Language and display 
result",
+                               "operationId": "eval-language",
+                               "requestBody": {
+                                       "content": {
+                                               "application\/json": {
+                                                       "schema": {
+                                                               "type": 
"object",
+                                                               "properties": {
+                                                                       "body": 
{
+                                                                               
"type": "string",
+                                                                               
"description": "Optional message body"
+                                                                       },
+                                                                       
"headers": {
+                                                                               
"type": "string",
+                                                                               
"description": "Optional message headers"
+                                                                       },
+                                                                       
"language": {
+                                                                               
"type": "string",
+                                                                               
"default": "simple",
+                                                                               
"description": "The language to use"
+                                                                       },
+                                                                       
"predicate": {
+                                                                               
"type": "boolean",
+                                                                               
"default": false,
+                                                                               
"description": "Whether to execute as predicate (use expression by default)"
+                                                                       },
+                                                                       
"template": {
+                                                                               
"type": "string",
+                                                                               
"description": "Template to use for executing simple language function"
+                                                                       },
+                                                                       
"variables": {
+                                                                               
"type": "string",
+                                                                               
"description": "Optional exchange variables"
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               },
+                               "responses": {
+                                       "200": {
+                                               "description": "Evaluate 
Language output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/event": {
+                       "get": {
+                               "summary": "Camel Events",
+                               "description": "The most recent Camel events",
+                               "operationId": "event",
+                               "responses": {
+                                       "200": {
+                                               "description": "Camel Events 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/fault-tolerance": {
+                       "get": {
+                               "summary": "MicroProfile Circuit Breaker",
+                               "description": "Display circuit breaker 
information",
+                               "operationId": "fault-tolerance",
+                               "responses": {
+                                       "200": {
+                                               "description": "MicroProfile 
Circuit Breaker output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/gc": {
+                       "get": {
+                               "summary": "Garbage Collector",
+                               "description": "Displays Garbage Collector 
information",
+                               "operationId": "gc",
+                               "responses": {
+                                       "200": {
+                                               "description": "Garbage 
Collector output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/gcp-secrets": {
+                       "get": {
+                               "summary": "GCP Secrets",
+                               "description": "GCP Secret Manager",
+                               "operationId": "gcp-secrets",
+                               "responses": {
+                                       "200": {
+                                               "description": "GCP Secrets 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/groovy": {
+                       "get": {
+                               "summary": "Groovy",
+                               "description": "Groovy Language",
+                               "operationId": "groovy",
+                               "responses": {
+                                       "200": {
+                                               "description": "Groovy output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/hashicorp-secrets": {
+                       "get": {
+                               "summary": "HashiCorp Secrets",
+                               "description": "HashiCorp Vault Secrets",
+                               "operationId": "hashicorp-secrets",
+                               "responses": {
+                                       "200": {
+                                               "description": "HashiCorp 
Secrets output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/health": {
+                       "get": {
+                               "summary": "Health Check",
+                               "description": "Health Check Status",
+                               "operationId": "health",
+                               "parameters": [
+                                       {
+                                               "name": "exposureLevel",
+                                               "in": "query",
+                                               "description": "Exposure level 
for health check details",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "string",
+                                                       "default": "default",
+                                                       "enum": [
+                                                               "default",
+                                                               "oneline",
+                                                               "full"
+                                                       ]
+                                               }
+                                       }
+                               ],
+                               "responses": {
+                                       "200": {
+                                               "description": "Health Check 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/heap-dump": {
+                       "post": {
+                               "summary": "Heap Dump",
+                               "description": "Write a heap dump (.hprof) file 
for deep memory analysis",
+                               "operationId": "heap-dump",
+                               "requestBody": {
+                                       "content": {
+                                               "application\/json": {
+                                                       "schema": {
+                                                               "type": 
"object",
+                                                               "properties": {
+                                                                       "live": 
{
+                                                                               
"type": "boolean",
+                                                                               
"default": true,
+                                                                               
"description": "Whether to dump only live objects (default true)"
+                                                                       },
+                                                                       "name": 
{
+                                                                               
"type": "string",
+                                                                               
"description": "File name for the heap dump (without .hprof extension)"
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               },
+                               "responses": {
+                                       "200": {
+                                               "description": "Heap Dump 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/heap-histogram": {
+                       "get": {
+                               "summary": "Heap Histogram",
+                               "description": "Displays class-level heap 
memory usage",
+                               "operationId": "heap-histogram",
+                               "parameters": [
+                                       {
+                                               "name": "limit",
+                                               "in": "query",
+                                               "description": "Limits the 
number of classes displayed",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "integer",
+                                                       "default": 100
+                                               }
+                                       }
+                               ],
+                               "responses": {
+                                       "200": {
+                                               "description": "Heap Histogram 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/ibm-secrets": {
+                       "get": {
+                               "summary": "IBM Secrets",
+                               "description": "IBM Secrets Manager",
+                               "operationId": "ibm-secrets",
+                               "responses": {
+                                       "200": {
+                                               "description": "IBM Secrets 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/inflight": {
+                       "get": {
+                               "summary": "Inflight Exchanges",
+                               "description": "Display inflight exchanges",
+                               "operationId": "inflight",
+                               "parameters": [
+                                       {
+                                               "name": "filter",
+                                               "in": "query",
+                                               "description": "Filters the 
routes matching by route id, route uri",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "string"
+                                               }
+                                       },
+                                       {
+                                               "name": "limit",
+                                               "in": "query",
+                                               "description": "Limits the 
number of entries displayed",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "integer"
+                                               }
+                                       }
+                               ],
+                               "responses": {
+                                       "200": {
+                                               "description": "Inflight 
Exchanges output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/internal-tasks": {
+                       "get": {
+                               "summary": "Internal Tasks",
+                               "description": "Display information about 
internal tasks",
+                               "operationId": "internal-tasks",
+                               "responses": {
+                                       "200": {
+                                               "description": "Internal Tasks 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/java-security": {
+                       "get": {
+                               "summary": "Java Security",
+                               "description": "Displays Java Security (JSSE) 
information",
+                               "operationId": "java-security",
+                               "responses": {
+                                       "200": {
+                                               "description": "Java Security 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/jfr": {
+                       "post": {
+                               "summary": "JFR Runtime Instrumentation",
+                               "description": "Status and live control of 
camel-jfr runtime instrumentation",
+                               "operationId": "jfr",
+                               "requestBody": {
+                                       "content": {
+                                               "application\/json": {
+                                                       "schema": {
+                                                               "type": 
"object",
+                                                               "properties": {
+                                                                       
"command": {
+                                                                               
"type": "string",
+                                                                               
"default": "status",
+                                                                               
"enum": [
+                                                                               
        "status",
+                                                                               
        "enable",
+                                                                               
        "disable",
+                                                                               
        "jfc",
+                                                                               
        "snapshot"
+                                                                               
],
+                                                                               
"description": "Command to perform"
+                                                                       },
+                                                                       
"disable": {
+                                                                               
"type": "string",
+                                                                               
"description": "Comma separated list of events to disable in the generated jfc 
settings overlay"
+                                                                       },
+                                                                       
"event": {
+                                                                               
"type": "string",
+                                                                               
"default": "all",
+                                                                               
"enum": [
+                                                                               
        "all",
+                                                                               
        "route",
+                                                                               
        "processor",
+                                                                               
        "exchange",
+                                                                               
        "send",
+                                                                               
        "failed",
+                                                                               
        "redelivery"
+                                                                               
],
+                                                                               
"description": "The runtime event to enable or disable, or all for every event"
+                                                                       },
+                                                                       
"limit": {
+                                                                               
"type": "integer",
+                                                                               
"default": 50,
+                                                                               
"description": "Maximum number of failure and redelivery entries to return in a 
snapshot"
+                                                                       },
+                                                                       
"routeId": {
+                                                                               
"type": "string",
+                                                                               
"description": "Filter snapshot results to the given route id"
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               },
+                               "responses": {
+                                       "200": {
+                                               "description": "JFR Runtime 
Instrumentation output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/jfr-memory-leak": {
+                       "post": {
+                               "summary": "JFR Memory Leak",
+                               "description": "JFR-based old object sampling 
for memory leak diagnosis",
+                               "operationId": "jfr-memory-leak",
+                               "requestBody": {
+                                       "content": {
+                                               "application\/json": {
+                                                       "schema": {
+                                                               "type": 
"object",
+                                                               "properties": {
+                                                                       
"command": {
+                                                                               
"type": "string",
+                                                                               
"default": "status",
+                                                                               
"enum": [
+                                                                               
        "start",
+                                                                               
        "stop",
+                                                                               
        "status",
+                                                                               
        "query",
+                                                                               
        "compare"
+                                                                               
],
+                                                                               
"description": "Command to execute"
+                                                                       },
+                                                                       
"duration": {
+                                                                               
"type": "integer",
+                                                                               
"default": 0,
+                                                                               
"description": "Recording duration in seconds (0 means manual stop)"
+                                                                       },
+                                                                       
"limit": {
+                                                                               
"type": "integer",
+                                                                               
"default": 100,
+                                                                               
"description": "Limits the number of entries displayed"
+                                                                       },
+                                                                       
"minSize": {
+                                                                               
"type": "integer",
+                                                                               
"default": 0,
+                                                                               
"description": "Minimum object size in bytes to include in results"
+                                                                       },
+                                                                       
"stacktrace": {
+                                                                               
"type": "boolean",
+                                                                               
"default": false,
+                                                                               
"description": "Whether to include stack traces in the output"
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               },
+                               "responses": {
+                                       "200": {
+                                               "description": "JFR Memory Leak 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/jvm": {
+                       "get": {
+                               "summary": "JVM",
+                               "description": "Displays JVM information",
+                               "operationId": "jvm",
+                               "responses": {
+                                       "200": {
+                                               "description": "JVM output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/kafka": {
+                       "get": {
+                               "summary": "Kafka",
+                               "description": "Apache Kafka",
+                               "operationId": "kafka",
+                               "parameters": [
+                                       {
+                                               "name": "committed",
+                                               "in": "query",
+                                               "description": "Whether to 
include committed offset (sync operation to Kafka broker)",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": false
+                                               }
+                                       }
+                               ],
+                               "responses": {
+                                       "200": {
+                                               "description": "Kafka output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/kubernetes-configmaps": {
+                       "get": {
+                               "summary": "Kubernetes Config Maps",
+                               "description": "Kubernetes Cluster Config Maps",
+                               "operationId": "kubernetes-configmaps",
+                               "responses": {
+                                       "200": {
+                                               "description": "Kubernetes 
Config Maps output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/kubernetes-secrets": {
+                       "get": {
+                               "summary": "Kubernetes Secrets",
+                               "description": "Kubernetes Cluster Secrets",
+                               "operationId": "kubernetes-secrets",
+                               "responses": {
+                                       "200": {
+                                               "description": "Kubernetes 
Secrets output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/log": {
+                       "get": {
+                               "summary": "Log",
+                               "description": "Logging framework",
+                               "operationId": "log",
+                               "responses": {
+                                       "200": {
+                                               "description": "Log output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/main-configuration": {
+                       "get": {
+                               "summary": "Main Configuration",
+                               "description": "Display Camel startup 
configuration",
+                               "operationId": "main-configuration",
+                               "responses": {
+                                       "200": {
+                                               "description": "Main 
Configuration output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/main-http-server": {
+                       "get": {
+                               "summary": "Main HTTP Server",
+                               "description": "Camel Main HTTP Server",
+                               "operationId": "main-http-server",
+                               "responses": {
+                                       "200": {
+                                               "description": "Main HTTP 
Server output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/memory": {
+                       "get": {
+                               "summary": "JVM Memory",
+                               "description": "Displays JVM memory 
information",
+                               "operationId": "memory",
+                               "responses": {
+                                       "200": {
+                                               "description": "JVM Memory 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/message-history": {
+                       "get": {
+                               "summary": "Message History",
+                               "description": "History of latest completed 
exchange",
+                               "operationId": "message-history",
+                               "parameters": [
+                                       {
+                                               "name": "codeLimit",
+                                               "in": "query",
+                                               "description": "Number of 
source code lines around the location to include",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "integer",
+                                                       "default": 5
+                                               }
+                                       }
+                               ],
+                               "responses": {
+                                       "200": {
+                                               "description": "Message History 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/micrometer": {
+                       "get": {
+                               "summary": "Micrometer",
+                               "description": "Display runtime metrics",
+                               "operationId": "micrometer",
+                               "parameters": [
+                                       {
+                                               "name": "filter",
+                                               "in": "query",
+                                               "description": "Filters 
matching metrics by name",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "string"
+                                               }
+                                       },
+                                       {
+                                               "name": "tags",
+                                               "in": "query",
+                                               "description": "Whether to 
include tags",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": true
+                                               }
+                                       }
+                               ],
+                               "responses": {
+                                       "200": {
+                                               "description": "Micrometer 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/opentelemetry": {
+                       "get": {
+                               "summary": "OpenTelemetry Spans",
+                               "description": "OpenTelemetry span data 
captured in dev mode",
+                               "operationId": "opentelemetry",
+                               "parameters": [
+                                       {
+                                               "name": "dump",
+                                               "in": "query",
+                                               "description": "Whether to dump 
span data",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "string",
+                                                       "enum": [
+                                                               "true",
+                                                               "false"
+                                                       ]
+                                               }
+                                       },
+                                       {
+                                               "name": "limit",
+                                               "in": "query",
+                                               "description": "Limits the 
number of spans dumped",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "integer",
+                                                       "default": 100
+                                               }
+                                       }
+                               ],
+                               "responses": {
+                                       "200": {
+                                               "description": "OpenTelemetry 
Spans output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/platform-http": {
+                       "get": {
+                               "summary": "Platform HTTP",
+                               "description": "Embedded HTTP Server",
+                               "operationId": "platform-http",
+                               "responses": {
+                                       "200": {
+                                               "description": "Platform HTTP 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/processor": {
+                       "post": {
+                               "summary": "Processor",
+                               "description": "Processor information",
+                               "operationId": "processor",
+                               "requestBody": {
+                                       "content": {
+                                               "application\/json": {
+                                                       "schema": {
+                                                               "type": 
"object",
+                                                               "properties": {
+                                                                       
"action": {
+                                                                               
"type": "string",
+                                                                               
"enum": [
+                                                                               
        "start",
+                                                                               
        "stop",
+                                                                               
        "enable",
+                                                                               
        "disable"
+                                                                               
],
+                                                                               
"description": "Action to perform such as start,stop,enable,disable on one or 
more processors"
+                                                                       },
+                                                                       
"filter": {
+                                                                               
"type": "string",
+                                                                               
"description": "Filters the processors matching by processor id, route id, or 
route group, and source location"
+                                                                       },
+                                                                       
"limit": {
+                                                                               
"type": "integer",
+                                                                               
"description": "Limits the number of entries displayed"
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               },
+                               "responses": {
+                                       "200": {
+                                               "description": "Processor 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/processor-detail": {
+                       "get": {
+                               "summary": "Processor Detail",
+                               "description": "Show configured options for all 
processors in a route",
+                               "operationId": "processor-detail",
+                               "parameters": [
+                                       {
+                                               "name": "routeId",
+                                               "in": "query",
+                                               "description": "The route id to 
get processor details for (use * for all routes)",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "string"
+                                               }
+                                       }
+                               ],
+                               "responses": {
+                                       "200": {
+                                               "description": "Processor 
Detail output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/producer": {
+                       "get": {
+                               "summary": "Producers",
+                               "description": "Display information about Camel 
producers",
+                               "operationId": "producer",
+                               "responses": {
+                                       "200": {
+                                               "description": "Producers 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/properties": {
+                       "get": {
+                               "summary": "Properties",
+                               "description": "Displays the properties loaded 
by Camel",
+                               "operationId": "properties",
+                               "responses": {
+                                       "200": {
+                                               "description": "Properties 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/quartz": {
+                       "get": {
+                               "summary": "Quartz",
+                               "description": "Quartz Scheduler",
+                               "operationId": "quartz",
+                               "responses": {
+                                       "200": {
+                                               "description": "Quartz output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/receive": {
+                       "post": {
+                               "summary": "Camel Receive",
+                               "description": "Consume messages from 
endpoints",
+                               "operationId": "receive",
+                               "requestBody": {
+                                       "content": {
+                                               "application\/json": {
+                                                       "schema": {
+                                                               "type": 
"object",
+                                                               "properties": {
+                                                                       "dump": 
{
+                                                                               
"type": "string",
+                                                                               
"enum": [
+                                                                               
        "true",
+                                                                               
        "false"
+                                                                               
],
+                                                                               
"description": "Whether to dump received messages"
+                                                                       },
+                                                                       
"enabled": {
+                                                                               
"type": "string",
+                                                                               
"enum": [
+                                                                               
        "true",
+                                                                               
        "false"
+                                                                               
],
+                                                                               
"description": "Whether to enable or disable receive mode"
+                                                                       },
+                                                                       
"endpoint": {
+                                                                               
"type": "string",
+                                                                               
"description": "Endpoint for where to receive messages (can also refer to a 
route id, endpoint pattern)"
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               },
+                               "responses": {
+                                       "200": {
+                                               "description": "Camel Receive 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/reload": {
+                       "post": {
+                               "summary": "Reload",
+                               "description": "Console for reloading running 
Camel",
+                               "operationId": "reload",
+                               "requestBody": {
+                                       "content": {
+                                               "application\/json": {
+                                                       "schema": {
+                                                               "type": 
"object",
+                                                               "properties": {
+                                                                       
"reload": {
+                                                                               
"type": "boolean",
+                                                                               
"default": false,
+                                                                               
"description": "Option to trigger reloading"
+                                                                       },
+                                                                       "wait": 
{
+                                                                               
"type": "boolean",
+                                                                               
"default": false,
+                                                                               
"description": "Option to wait for reloading to complete"
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               },
+                               "responses": {
+                                       "200": {
+                                               "description": "Reload output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/resilience4j": {
+                       "get": {
+                               "summary": "Resilience Circuit Breaker",
+                               "description": "Display circuit breaker 
information",
+                               "operationId": "resilience4j",
+                               "responses": {
+                                       "200": {
+                                               "description": "Resilience 
Circuit Breaker output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/rest": {
+                       "get": {
+                               "summary": "Rest",
+                               "description": "Rest DSL Registry information",
+                               "operationId": "rest",
+                               "responses": {
+                                       "200": {
+                                               "description": "Rest output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/rest-spec": {
+                       "get": {
+                               "summary": "Rest Spec",
+                               "description": "OpenAPI specification content 
for contract-first REST services",
+                               "operationId": "rest-spec",
+                               "parameters": [
+                                       {
+                                               "name": "filter",
+                                               "in": "query",
+                                               "description": "Filters 
specifications matching the given URI pattern",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "string"
+                                               }
+                                       }
+                               ],
+                               "responses": {
+                                       "200": {
+                                               "description": "Rest Spec 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/route": {
+                       "post": {
+                               "summary": "Route",
+                               "description": "Route information",
+                               "operationId": "route",
+                               "requestBody": {
+                                       "content": {
+                                               "application\/json": {
+                                                       "schema": {
+                                                               "type": 
"object",
+                                                               "properties": {
+                                                                       
"action": {
+                                                                               
"type": "string",
+                                                                               
"enum": [
+                                                                               
        "start",
+                                                                               
        "stop",
+                                                                               
        "suspend",
+                                                                               
        "resume"
+                                                                               
],
+                                                                               
"description": "Action to perform such as start,stop,suspend,resume on one or 
more routes"
+                                                                       },
+                                                                       
"filter": {
+                                                                               
"type": "string",
+                                                                               
"description": "Filters the routes matching by route id, route uri, or route 
group, and source location"
+                                                                       },
+                                                                       
"limit": {
+                                                                               
"type": "integer",
+                                                                               
"description": "Limits the number of entries displayed"
+                                                                       },
+                                                                       
"processors": {
+                                                                               
"type": "boolean",
+                                                                               
"default": false,
+                                                                               
"description": "Whether to include processors"
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               },
+                               "responses": {
+                                       "200": {
+                                               "description": "Route output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/route-controller": {
+                       "get": {
+                               "summary": "Route Controller",
+                               "description": "Route controller information",
+                               "operationId": "route-controller",
+                               "parameters": [
+                                       {
+                                               "name": "error",
+                                               "in": "query",
+                                               "description": "Whether to 
include error details",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": true
+                                               }
+                                       },
+                                       {
+                                               "name": "stacktrace",
+                                               "in": "query",
+                                               "description": "Whether to 
include stack traces",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": true
+                                               }
+                                       }
+                               ],
+                               "responses": {
+                                       "200": {
+                                               "description": "Route 
Controller output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/route-diagram": {
+                       "get": {
+                               "summary": "Route Diagram",
+                               "description": "Visual route diagrams",
+                               "operationId": "route-diagram",
+                               "parameters": [
+                                       {
+                                               "name": "autoRefresh",
+                                               "in": "query",
+                                               "description": "Whether to 
auto-refresh page every 5 seconds",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": true
+                                               }
+                                       },
+                                       {
+                                               "name": "external",
+                                               "in": "query",
+                                               "description": "Whether to 
include external systems (kafka, http, etc.) in topology mode",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": true
+                                               }
+                                       },
+                                       {
+                                               "name": "filter",
+                                               "in": "query",
+                                               "description": "Filters the 
routes matching by route id, route uri, and source location",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "string",
+                                                       "default": "*"
+                                               }
+                                       },
+                                       {
+                                               "name": "fontSize",
+                                               "in": "query",
+                                               "description": "The size of the 
font",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "integer",
+                                                       "default": 12
+                                               }
+                                       },
+                                       {
+                                               "name": "format",
+                                               "in": "query",
+                                               "description": "Output format: 
html (interactive web component), png (inline image), text or ascii (ASCII 
art), unicode (box-drawing characters)",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "string",
+                                                       "default": "html",
+                                                       "enum": [
+                                                               "html",
+                                                               "png",
+                                                               "text",
+                                                               "ascii",
+                                                               "unicode"
+                                                       ]
+                                               }
+                                       },
+                                       {
+                                               "name": "metric",
+                                               "in": "query",
+                                               "description": "Whether to 
include live metric counters",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": true
+                                               }
+                                       },
+                                       {
+                                               "name": "mode",
+                                               "in": "query",
+                                               "description": "Diagram mode: 
route or topology",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "string",
+                                                       "default": "route",
+                                                       "enum": [
+                                                               "route",
+                                                               "topology"
+                                                       ]
+                                               }
+                                       },
+                                       {
+                                               "name": "nodeLabel",
+                                               "in": "query",
+                                               "description": "Node label 
mode",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "string",
+                                                       "default": "code",
+                                                       "enum": [
+                                                               "code",
+                                                               "description",
+                                                               "both"
+                                                       ]
+                                               }
+                                       },
+                                       {
+                                               "name": "nodeWidth",
+                                               "in": "query",
+                                               "description": "The node width 
in pixels",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "integer",
+                                                       "default": 180
+                                               }
+                                       },
+                                       {
+                                               "name": "theme",
+                                               "in": "query",
+                                               "description": "Theme to use: 
dark, light, transparent, ascii, or unicode",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "string",
+                                                       "default": 
"transparent",
+                                                       "enum": [
+                                                               "dark",
+                                                               "light",
+                                                               "transparent",
+                                                               "ascii",
+                                                               "unicode"
+                                                       ]
+                                               }
+                                       }
+                               ],
+                               "responses": {
+                                       "200": {
+                                               "description": "Route Diagram 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/route-dump": {
+                       "get": {
+                               "summary": "Route Dump",
+                               "description": "Dump route in XML, YAML, or 
Java DSL format",
+                               "operationId": "route-dump",
+                               "parameters": [
+                                       {
+                                               "name": "filter",
+                                               "in": "query",
+                                               "description": "Filters the 
routes matching by route id, route uri, and source location",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "string"
+                                               }
+                                       },
+                                       {
+                                               "name": "format",
+                                               "in": "query",
+                                               "description": "To output in 
either xml, yaml, or java format",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "string",
+                                                       "enum": [
+                                                               "xml",
+                                                               "yaml",
+                                                               "java"
+                                                       ]
+                                               }
+                                       },
+                                       {
+                                               "name": "limit",
+                                               "in": "query",
+                                               "description": "Limits the 
number of entries displayed",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "integer"
+                                               }
+                                       },
+                                       {
+                                               "name": "uriAsParameters",
+                                               "in": "query",
+                                               "description": "Whether to 
expand URIs into separated key\/value parameters",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": false
+                                               }
+                                       }
+                               ],
+                               "responses": {
+                                       "200": {
+                                               "description": "Route Dump 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/route-group": {
+                       "post": {
+                               "summary": "Route Group",
+                               "description": "Route Group information",
+                               "operationId": "route-group",
+                               "requestBody": {
+                                       "content": {
+                                               "application\/json": {
+                                                       "schema": {
+                                                               "type": 
"object",
+                                                               "properties": {
+                                                                       
"action": {
+                                                                               
"type": "string",
+                                                                               
"enum": [
+                                                                               
        "start",
+                                                                               
        "stop"
+                                                                               
],
+                                                                               
"description": "Action to perform such as start or stop"
+                                                                       },
+                                                                       
"filter": {
+                                                                               
"type": "string",
+                                                                               
"description": "Filters the route groups matching by group id"
+                                                                       },
+                                                                       
"limit": {
+                                                                               
"type": "integer",
+                                                                               
"description": "Limits the number of entries displayed"
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               },
+                               "responses": {
+                                       "200": {
+                                               "description": "Route Group 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/route-structure": {
+                       "get": {
+                               "summary": "Route Structure",
+                               "description": "Dump route structure",
+                               "operationId": "route-structure",
+                               "parameters": [
+                                       {
+                                               "name": "brief",
+                                               "in": "query",
+                                               "description": "Whether to dump 
in brief mode (only overall structure, and no detailed options or expressions)",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": false
+                                               }
+                                       },
+                                       {
+                                               "name": "filter",
+                                               "in": "query",
+                                               "description": "Filters the 
routes matching by route id, route uri, and source location",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "string"
+                                               }
+                                       },
+                                       {
+                                               "name": "limit",
+                                               "in": "query",
+                                               "description": "Limits the 
number of entries displayed",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "integer"
+                                               }
+                                       },
+                                       {
+                                               "name": "metric",
+                                               "in": "query",
+                                               "description": "Whether to 
include metrics such as number of messages processed (from JMX)",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": false
+                                               }
+                                       }
+                               ],
+                               "responses": {
+                                       "200": {
+                                               "description": "Route Structure 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/route-topology": {
+                       "get": {
+                               "summary": "Route Topology",
+                               "description": "Route topology showing 
inter-route connections",
+                               "operationId": "route-topology",
+                               "parameters": [
+                                       {
+                                               "name": "external",
+                                               "in": "query",
+                                               "description": "Whether to 
include external systems (databases, messaging brokers, etc.) as nodes",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": false
+                                               }
+                                       },
+                                       {
+                                               "name": "metric",
+                                               "in": "query",
+                                               "description": "Whether to 
include live metrics (message counts) on nodes and edges",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": false
+                                               }
+                                       },
+                                       {
+                                               "name": "routes",
+                                               "in": "query",
+                                               "description": "Whether to 
include route structure data in the response",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": false
+                                               }
+                                       }
+                               ],
+                               "responses": {
+                                       "200": {
+                                               "description": "Route Topology 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/send": {
+                       "post": {
+                               "summary": "Camel Send",
+                               "description": "Send messages to endpoints",
+                               "operationId": "send",
+                               "requestBody": {
+                                       "content": {
+                                               "application\/json": {
+                                                       "schema": {
+                                                               "type": 
"object",
+                                                               "properties": {
+                                                                       "body": 
{
+                                                                               
"type": "string",
+                                                                               
"description": "The message body to send. Can refer to files using file: prefix"
+                                                                       },
+                                                                       
"bodyMaxChars": {
+                                                                               
"type": "integer",
+                                                                               
"default": 32768,
+                                                                               
"description": "Maximum size of the message body to include in the dump"
+                                                                       },
+                                                                       
"endpoint": {
+                                                                               
"type": "string",
+                                                                               
"description": "Endpoint for where to send messages (can also refer to a route 
id, endpoint pattern)"
+                                                                       },
+                                                                       
"exchangePattern": {
+                                                                               
"type": "string",
+                                                                               
"enum": [
+                                                                               
        "InOnly",
+                                                                               
        "InOut"
+                                                                               
],
+                                                                               
"description": "Exchange pattern when sending"
+                                                                       },
+                                                                       "poll": 
{
+                                                                               
"type": "boolean",
+                                                                               
"description": "Whether to poll message from the endpoint instead of sending"
+                                                                       },
+                                                                       
"pollTimeout": {
+                                                                               
"type": "integer",
+                                                                               
"default": 20000,
+                                                                               
"description": "Timeout when using poll mode"
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               },
+                               "responses": {
+                                       "200": {
+                                               "description": "Camel Send 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/service": {
+                       "get": {
+                               "summary": "Services",
+                               "description": "Services used for network 
communication with clients",
+                               "operationId": "service",
+                               "responses": {
+                                       "200": {
+                                               "description": "Services 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/sftp": {
+                       "get": {
+                               "summary": "SFTP",
+                               "description": "Secure FTP using JSCH",
+                               "operationId": "sftp",
+                               "responses": {
+                                       "200": {
+                                               "description": "SFTP output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/simple-language": {
+                       "get": {
+                               "summary": "Simple Language",
+                               "description": "Display simple language 
details",
+                               "operationId": "simple-language",
+                               "responses": {
+                                       "200": {
+                                               "description": "Simple Language 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/source": {
+                       "get": {
+                               "summary": "Source",
+                               "description": "Dump route source code",
+                               "operationId": "source",
+                               "parameters": [
+                                       {
+                                               "name": "filter",
+                                               "in": "query",
+                                               "description": "Filters the 
routes matching by route id, route uri, and source location",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "string"
+                                               }
+                                       },
+                                       {
+                                               "name": "limit",
+                                               "in": "query",
+                                               "description": "Limits the 
number of entries displayed",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "integer"
+                                               }
+                                       }
+                               ],
+                               "responses": {
+                                       "200": {
+                                               "description": "Source output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/sql-query": {
+                       "post": {
+                               "summary": "SQL Query",
+                               "description": "Execute SQL queries on 
DataSource beans",
+                               "operationId": "sql-query",
+                               "requestBody": {
+                                       "content": {
+                                               "application\/json": {
+                                                       "schema": {
+                                                               "type": 
"object",
+                                                               "properties": {
+                                                                       
"actionType": {
+                                                                               
"type": "string",
+                                                                               
"default": "query",
+                                                                               
"enum": [
+                                                                               
        "query",
+                                                                               
        "update-row"
+                                                                               
],
+                                                                               
"description": "Action type: query (default) or update-row"
+                                                                       },
+                                                                       
"columnValues": {
+                                                                               
"type": "string",
+                                                                               
"description": "Changed column-value pairs as JSON string for update-row action"
+                                                                       },
+                                                                       
"datasource": {
+                                                                               
"type": "string",
+                                                                               
"description": "Name of the DataSource bean in the registry (auto-detected if 
only one exists)"
+                                                                       },
+                                                                       
"maxRows": {
+                                                                               
"type": "integer",
+                                                                               
"default": 100,
+                                                                               
"description": "Maximum number of rows to return"
+                                                                       },
+                                                                       
"primaryKeyValues": {
+                                                                               
"type": "string",
+                                                                               
"description": "Primary key column-value pairs as JSON string for update-row 
action"
+                                                                       },
+                                                                       
"queryTimeout": {
+                                                                               
"type": "integer",
+                                                                               
"default": 30,
+                                                                               
"description": "Query timeout in seconds"
+                                                                       },
+                                                                       "sql": {
+                                                                               
"type": "string",
+                                                                               
"description": "The SQL query to execute"
+                                                                       },
+                                                                       
"table": {
+                                                                               
"type": "string",
+                                                                               
"description": "Table name for update-row action"
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               },
+                               "responses": {
+                                       "200": {
+                                               "description": "SQL Query 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/sql-trace": {
+                       "get": {
+                               "summary": "SQL Trace",
+                               "description": "Trace SQL query executions",
+                               "operationId": "sql-trace",
+                               "responses": {
+                                       "200": {
+                                               "description": "SQL Trace 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/startup-recorder": {
+                       "get": {
+                               "summary": "Startup Recorder",
+                               "description": "Starting recording information",
+                               "operationId": "startup-recorder",
+                               "responses": {
+                                       "200": {
+                                               "description": "Startup 
Recorder output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/stub": {
+                       "get": {
+                               "summary": "Stub",
+                               "description": "Browse messages on stub 
endpoints",
+                               "operationId": "stub",
+                               "parameters": [
+                                       {
+                                               "name": "browse",
+                                               "in": "query",
+                                               "description": "Whether to 
browse messages",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": false
+                                               }
+                                       },
+                                       {
+                                               "name": "filter",
+                                               "in": "query",
+                                               "description": "Filters the 
routes matching by queue name",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "string"
+                                               }
+                                       },
+                                       {
+                                               "name": "format",
+                                               "in": "query",
+                                               "description": "To use either 
xml or json output format",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "string",
+                                                       "enum": [
+                                                               "xml",
+                                                               "json"
+                                                       ]
+                                               }
+                                       },
+                                       {
+                                               "name": "limit",
+                                               "in": "query",
+                                               "description": "Limits the 
number of messages dumped",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "integer"
+                                               }
+                                       }
+                               ],
+                               "responses": {
+                                       "200": {
+                                               "description": "Stub output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/system-properties": {
+                       "get": {
+                               "summary": "System Properties",
+                               "description": "Displays Java System 
Properties",
+                               "operationId": "system-properties",
+                               "responses": {
+                                       "200": {
+                                               "description": "System 
Properties output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/thread": {
+                       "get": {
+                               "summary": "Thread",
+                               "description": "Displays JVM Threads 
information",
+                               "operationId": "thread",
+                               "parameters": [
+                                       {
+                                               "name": "stackTrace",
+                                               "in": "query",
+                                               "description": "Whether to 
include thread stack traces",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": false
+                                               }
+                                       }
+                               ],
+                               "responses": {
+                                       "200": {
+                                               "description": "Thread output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/top": {
+                       "get": {
+                               "summary": "Top Routes",
+                               "description": "Display the top routes",
+                               "operationId": "top",
+                               "parameters": [
+                                       {
+                                               "name": "filter",
+                                               "in": "query",
+                                               "description": "Filters the 
routes and processors matching by route id, route uri, processor id, and source 
location",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "string"
+                                               }
+                                       },
+                                       {
+                                               "name": "limit",
+                                               "in": "query",
+                                               "description": "Limits the 
number of entries displayed",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "integer"
+                                               }
+                                       }
+                               ],
+                               "responses": {
+                                       "200": {
+                                               "description": "Top Routes 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/trace": {
+                       "post": {
+                               "summary": "Camel Tracing",
+                               "description": "Trace routed messages",
+                               "operationId": "trace",
+                               "requestBody": {
+                                       "content": {
+                                               "application\/json": {
+                                                       "schema": {
+                                                               "type": 
"object",
+                                                               "properties": {
+                                                                       "dump": 
{
+                                                                               
"type": "string",
+                                                                               
"enum": [
+                                                                               
        "true",
+                                                                               
        "false"
+                                                                               
],
+                                                                               
"description": "Whether to dump trace messages"
+                                                                       },
+                                                                       
"enabled": {
+                                                                               
"type": "string",
+                                                                               
"enum": [
+                                                                               
        "true",
+                                                                               
        "false"
+                                                                               
],
+                                                                               
"description": "Whether to enable or disable tracing"
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               },
+                               "responses": {
+                                       "200": {
+                                               "description": "Camel Tracing 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/transformers": {
+                       "get": {
+                               "summary": "Data Type Transformers",
+                               "description": "Data-type transformer 
information",
+                               "operationId": "transformers",
+                               "responses": {
+                                       "200": {
+                                               "description": "Data Type 
Transformers output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/type-converters": {
+                       "get": {
+                               "summary": "Type Converters",
+                               "description": "Camel Type Converter 
information",
+                               "operationId": "type-converters",
+                               "responses": {
+                                       "200": {
+                                               "description": "Type Converters 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/variables": {
+                       "get": {
+                               "summary": "Variables",
+                               "description": "Displays variables",
+                               "operationId": "variables",
+                               "responses": {
+                                       "200": {
+                                               "description": "Variables 
output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "\/q\/dev\/vertx-websocket": {
+                       "get": {
+                               "summary": "Vert.x WebSocket",
+                               "description": "Vert.x WebSocket consumer 
details",
+                               "operationId": "vertx-websocket",
+                               "parameters": [
+                                       {
+                                               "name": "includeHeaders",
+                                               "in": "query",
+                                               "description": "Whether to 
include WebSocket peer connection header details in the output",
+                                               "required": false,
+                                               "schema": {
+                                                       "type": "boolean",
+                                                       "default": true
+                                               }
+                                       }
+                               ],
+                               "responses": {
+                                       "200": {
+                                               "description": "Vert.x 
WebSocket output",
+                                               "content": {
+                                                       "application\/json": {
+                                                               
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
diff --git 
a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java
 
b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java
index e6da89abff48..d71a426840bc 100644
--- 
a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java
+++ 
b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java
@@ -599,6 +599,11 @@ public interface CamelCatalog {
      */
     String listDevConsolesAsJson();
 
+    /**
+     * The OpenAPI 3.0 specification describing every dev console endpoint, 
aggregated across all dev consoles.
+     */
+    String devConsolesOpenApiSpec();
+
     /**
      * Lists all the models (EIPs) summary details in JSon
      */
diff --git 
a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java
 
b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java
index 8bb8ba3d8d83..67d0a9c19138 100644
--- 
a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java
+++ 
b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java
@@ -546,6 +546,11 @@ public class DefaultCamelCatalog extends 
AbstractCachingCamelCatalog implements
                 .toList()));
     }
 
+    @Override
+    public String devConsolesOpenApiSpec() {
+        return cache(BASE_RESOURCE_DIR + "/dev-consoles-openapi.json", 
this::loadResource);
+    }
+
     @Override
     public String listModelsAsJson() {
         return cache(LIST_MODELS_AS_JSON, () -> 
JsonMapper.serialize(findModelNames().stream()
diff --git 
a/catalog/camel-catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
 
b/catalog/camel-catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
index f5217b7dbe86..dda65723921c 100644
--- 
a/catalog/camel-catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
+++ 
b/catalog/camel-catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
@@ -38,6 +38,7 @@ import org.apache.camel.tooling.model.LanguageModel;
 import org.apache.camel.tooling.model.PojoBeanModel;
 import org.apache.camel.tooling.model.ReleaseModel;
 import org.apache.camel.tooling.model.SecurityAdvisoryModel;
+import org.apache.camel.util.json.JsonObject;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
@@ -1772,6 +1773,30 @@ public class CamelCatalogTest {
         Assertions.assertTrue(advisory.getComponents().contains("camel-bean"));
     }
 
+    @Test
+    public void devConsolesOpenApiSpec() {
+        String json = catalog.devConsolesOpenApiSpec();
+        Assertions.assertNotNull(json);
+
+        JsonObject doc = JsonMapper.deserialize(json);
+        Assertions.assertEquals("3.0.3", doc.getString("openapi"));
+
+        JsonObject paths = doc.getJsonObject("paths");
+        Assertions.assertNotNull(paths);
+
+        JsonObject context = paths.getJsonObject("/q/dev/context");
+        Assertions.assertNotNull(context);
+        Assertions.assertNotNull(context.getJsonObject("get"));
+        Assertions.assertNull(context.get("post"));
+
+        JsonObject route = paths.getJsonObject("/q/dev/route");
+        Assertions.assertNotNull(route);
+        Assertions.assertNull(route.get("get"));
+        JsonObject post = route.getJsonObject("post");
+        Assertions.assertNotNull(post);
+        Assertions.assertNotNull(post.getJsonObject("requestBody"));
+    }
+
     @Test
     public void testFindPojoBeanNames() {
         List<String> names = catalog.findBeansNames();
diff --git a/core/camel-console/pom.xml b/core/camel-console/pom.xml
index c09ab7f98d73..e6f22770d58a 100644
--- a/core/camel-console/pom.xml
+++ b/core/camel-console/pom.xml
@@ -49,6 +49,11 @@
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-util-json</artifactId>
         </dependency>
+        <!-- tooling model (for building the api console's OpenAPI spec) -->
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-tooling-model</artifactId>
+        </dependency>
 
         <!-- testing -->
         <dependency>
diff --git 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/ApiDevConsole.java
 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/ApiDevConsole.java
index 2fe27561dda6..2b1cc6b1c101 100644
--- 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/ApiDevConsole.java
+++ 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/ApiDevConsole.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.impl.console;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
@@ -24,7 +25,9 @@ import org.apache.camel.console.DevConsoleRegistry;
 import org.apache.camel.spi.Configurer;
 import org.apache.camel.spi.annotations.DevConsole;
 import org.apache.camel.support.console.AbstractDevConsole;
-import org.apache.camel.util.json.JsonArray;
+import org.apache.camel.tooling.model.DevConsoleModel;
+import org.apache.camel.tooling.model.DevConsoleOpenApiHelper;
+import org.apache.camel.tooling.model.JsonMapper;
 import org.apache.camel.util.json.JsonObject;
 import org.apache.camel.util.json.Jsoner;
 
@@ -63,183 +66,37 @@ public class ApiDevConsole extends AbstractDevConsole {
     }
 
     private String buildOpenApi() {
-        JsonObject root = new JsonObject();
-        root.put("openapi", "3.0.3");
-
-        JsonObject info = new JsonObject();
-        info.put("title", "Camel Dev Console API");
-        info.put("version", getCamelContext().getVersion());
-        root.put("info", info);
-
-        JsonObject paths = new JsonObject();
+        List<DevConsoleModel> models = new ArrayList<>();
 
         DevConsoleRegistry dcr = getCamelContext().getCamelContextExtension()
                 .getContextPlugin(DevConsoleRegistry.class);
         if (dcr != null && dcr.isEnabled()) {
-            List<org.apache.camel.console.DevConsole> consoles = dcr.stream()
-                    .sorted((a, b) -> a.getId().compareToIgnoreCase(b.getId()))
-                    .toList();
-
-            for (org.apache.camel.console.DevConsole console : consoles) {
-                String id = console.getId();
-                boolean readOnly = console.isReadOnly();
-
-                JsonObject pathItem = new JsonObject();
-                JsonObject operation = new JsonObject();
-                operation.put("summary", console.getDisplayName());
-                operation.put("description", console.getDescription());
-                operation.put("operationId", id);
-
-                if (readOnly) {
-                    JsonArray parameters = buildConsoleParameters(id);
-                    if (parameters != null) {
-                        operation.put("parameters", parameters);
-                    }
-                } else {
-                    JsonObject requestBody = buildConsoleRequestBody(id);
-                    if (requestBody != null) {
-                        operation.put("requestBody", requestBody);
-                    }
-                }
-
-                JsonObject responses = new JsonObject();
-                JsonObject ok = new JsonObject();
-                ok.put("description", console.getDisplayName() + " output");
-                JsonObject responseContent = new JsonObject();
-                responseContent.put("application/json", new JsonObject());
-                ok.put("content", responseContent);
-                responses.put("200", ok);
-                operation.put("responses", responses);
-
-                pathItem.put(readOnly ? "get" : "post", operation);
-                paths.put("/q/dev/" + id, pathItem);
+            for (org.apache.camel.console.DevConsole console : 
dcr.stream().toList()) {
+                models.add(buildConsoleModel(console));
             }
         }
 
-        root.put("paths", paths);
+        JsonObject root = DevConsoleOpenApiHelper.buildOpenApiDocument(models, 
getCamelContext().getVersion());
         return Jsoner.prettyPrint(root.toJson());
     }
 
     /**
-     * Loads and parses the option schema for the given console.
-     *
-     * @return the parsed options, or null if the console has no options or 
the schema could not be loaded
+     * Builds the {@link DevConsoleModel} for the given live console: its 
options are loaded from the console's
+     * generated catalog schema, while id/displayName/description/readOnly 
come from the live instance.
      */
-    private JsonObject loadConsoleOptions(String consoleId) {
+    private DevConsoleModel 
buildConsoleModel(org.apache.camel.console.DevConsole console) {
+        DevConsoleModel model;
         try {
             String json = ((CatalogCamelContext) getCamelContext())
-                    .getDevConsoleParameterJsonSchema(consoleId);
-            if (json == null) {
-                return null;
-            }
-            Object parsed = Jsoner.deserialize(json);
-            if (!(parsed instanceof JsonObject jo)) {
-                return null;
-            }
-            Object optionsObj = jo.get("options");
-            if (!(optionsObj instanceof JsonObject opts) || opts.isEmpty()) {
-                return null;
-            }
-            return opts;
+                    .getDevConsoleParameterJsonSchema(console.getId());
+            model = json != null ? JsonMapper.generateDevConsoleModel(json) : 
new DevConsoleModel();
         } catch (Exception e) {
-            // ignore
-            return null;
-        }
-    }
-
-    private JsonObject buildConsoleRequestBody(String consoleId) {
-        JsonObject opts = loadConsoleOptions(consoleId);
-        if (opts == null) {
-            return null;
-        }
-
-        JsonObject properties = new JsonObject();
-        JsonArray required = new JsonArray();
-        for (Map.Entry<String, Object> entry : opts.entrySet()) {
-            String name = entry.getKey();
-            if (!(entry.getValue() instanceof JsonObject opt)) {
-                continue;
-            }
-            JsonObject prop = new JsonObject();
-            String type = opt.getString("type");
-            if (type != null) {
-                prop.put("type", type);
-            }
-            String description = opt.getString("description");
-            if (description != null) {
-                prop.put("description", description);
-            }
-            Object defaultValue = opt.get("defaultValue");
-            if (defaultValue != null) {
-                prop.put("default", defaultValue);
-            }
-            Object enumValues = opt.get("enum");
-            if (enumValues instanceof JsonArray ea && !ea.isEmpty()) {
-                prop.put("enum", enumValues);
-            }
-            properties.put(name, prop);
-
-            Boolean req = opt.getBoolean("required");
-            if (req != null && req) {
-                required.add(name);
-            }
-        }
-
-        JsonObject schema = new JsonObject();
-        schema.put("type", "object");
-        schema.put("properties", properties);
-        if (!required.isEmpty()) {
-            schema.put("required", required);
-        }
-
-        JsonObject mediaType = new JsonObject();
-        mediaType.put("schema", schema);
-        JsonObject content = new JsonObject();
-        content.put("application/json", mediaType);
-        JsonObject requestBody = new JsonObject();
-        requestBody.put("content", content);
-        return requestBody;
-    }
-
-    private JsonArray buildConsoleParameters(String consoleId) {
-        JsonObject opts = loadConsoleOptions(consoleId);
-        if (opts == null) {
-            return null;
-        }
-
-        JsonArray parameters = new JsonArray();
-        for (Map.Entry<String, Object> entry : opts.entrySet()) {
-            String name = entry.getKey();
-            if (!(entry.getValue() instanceof JsonObject opt)) {
-                continue;
-            }
-            JsonObject param = new JsonObject();
-            param.put("name", name);
-            param.put("in", "query");
-            String description = opt.getString("description");
-            if (description != null) {
-                param.put("description", description);
-            }
-            Boolean req = opt.getBoolean("required");
-            param.put("required", req != null && req);
-
-            JsonObject schema = new JsonObject();
-            String type = opt.getString("type");
-            if (type != null) {
-                schema.put("type", type);
-            }
-            Object defaultValue = opt.get("defaultValue");
-            if (defaultValue != null) {
-                schema.put("default", defaultValue);
-            }
-            Object enumValues = opt.get("enum");
-            if (enumValues instanceof JsonArray ea && !ea.isEmpty()) {
-                schema.put("enum", enumValues);
-            }
-            param.put("schema", schema);
-
-            parameters.add(param);
+            model = new DevConsoleModel();
         }
-        return parameters.isEmpty() ? null : parameters;
+        model.setName(console.getId());
+        model.setTitle(console.getDisplayName());
+        model.setDescription(console.getDescription());
+        model.setReadOnly(console.isReadOnly());
+        return model;
     }
 }
diff --git 
a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/DevConsoleModel.java
 
b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/DevConsoleModel.java
index 48eea3fabc1a..74a4afa5ee0f 100644
--- 
a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/DevConsoleModel.java
+++ 
b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/DevConsoleModel.java
@@ -19,6 +19,7 @@ package org.apache.camel.tooling.model;
 public class DevConsoleModel extends 
ArtifactModel<DevConsoleModel.DevConsoleOptionModel> {
 
     protected String group;
+    protected boolean readOnly = true;
 
     public DevConsoleModel() {
     }
@@ -31,6 +32,14 @@ public class DevConsoleModel extends 
ArtifactModel<DevConsoleModel.DevConsoleOpt
         this.group = group;
     }
 
+    public boolean isReadOnly() {
+        return readOnly;
+    }
+
+    public void setReadOnly(boolean readOnly) {
+        this.readOnly = readOnly;
+    }
+
     @Override
     public Kind getKind() {
         return Kind.console;
diff --git 
a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/DevConsoleOpenApiHelper.java
 
b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/DevConsoleOpenApiHelper.java
new file mode 100644
index 000000000000..4bbdbd40e855
--- /dev/null
+++ 
b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/DevConsoleOpenApiHelper.java
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.tooling.model;
+
+import java.util.List;
+
+import org.apache.camel.tooling.model.DevConsoleModel.DevConsoleOptionModel;
+import org.apache.camel.util.json.JsonArray;
+import org.apache.camel.util.json.JsonObject;
+
+/**
+ * Builds an OpenAPI 3.0 specification describing the dev console {@code 
/q/dev/{id}} endpoints, from
+ * {@link DevConsoleModel} instances. Shared between the live {@code api} dev 
console (which sources models from a
+ * running {@code DevConsoleRegistry}) and the build-time catalog generator 
(which sources models from the aggregated
+ * catalog {@code dev-console/*.json} files), so both produce identical output.
+ */
+public final class DevConsoleOpenApiHelper {
+
+    private DevConsoleOpenApiHelper() {
+    }
+
+    /**
+     * Builds a full OpenAPI document for the given consoles.
+     */
+    public static JsonObject buildOpenApiDocument(List<DevConsoleModel> 
consoles, String version) {
+        JsonObject root = new JsonObject();
+        root.put("openapi", "3.0.3");
+
+        JsonObject info = new JsonObject();
+        info.put("title", "Camel Dev Console API");
+        info.put("version", version);
+        root.put("info", info);
+
+        JsonObject paths = new JsonObject();
+        consoles.stream()
+                .sorted((a, b) -> a.getName().compareToIgnoreCase(b.getName()))
+                .forEach(model -> paths.put("/q/dev/" + model.getName(), 
buildPathItem(model)));
+        root.put("paths", paths);
+
+        return root;
+    }
+
+    /**
+     * Builds the OpenAPI path item ({@code get} or {@code post} operation) 
for a single console.
+     */
+    public static JsonObject buildPathItem(DevConsoleModel model) {
+        JsonObject operation = new JsonObject();
+        operation.put("summary", model.getTitle());
+        operation.put("description", model.getDescription());
+        operation.put("operationId", model.getName());
+
+        boolean readOnly = model.isReadOnly();
+        if (readOnly) {
+            JsonArray parameters = buildParameters(model.getOptions());
+            if (parameters != null) {
+                operation.put("parameters", parameters);
+            }
+        } else {
+            JsonObject requestBody = buildRequestBody(model.getOptions());
+            if (requestBody != null) {
+                operation.put("requestBody", requestBody);
+            }
+        }
+
+        JsonObject responses = new JsonObject();
+        JsonObject ok = new JsonObject();
+        ok.put("description", model.getTitle() + " output");
+        JsonObject responseContent = new JsonObject();
+        responseContent.put("application/json", new JsonObject());
+        ok.put("content", responseContent);
+        responses.put("200", ok);
+        operation.put("responses", responses);
+
+        JsonObject pathItem = new JsonObject();
+        pathItem.put(readOnly ? "get" : "post", operation);
+        return pathItem;
+    }
+
+    private static JsonArray buildParameters(List<DevConsoleOptionModel> 
options) {
+        if (options == null || options.isEmpty()) {
+            return null;
+        }
+
+        JsonArray parameters = new JsonArray();
+        for (DevConsoleOptionModel opt : options) {
+            JsonObject param = new JsonObject();
+            param.put("name", opt.getName());
+            param.put("in", "query");
+            if (opt.getDescription() != null) {
+                param.put("description", opt.getDescription());
+            }
+            param.put("required", opt.isRequired());
+            param.put("schema", buildSchema(opt));
+            parameters.add(param);
+        }
+        return parameters;
+    }
+
+    private static JsonObject buildRequestBody(List<DevConsoleOptionModel> 
options) {
+        if (options == null || options.isEmpty()) {
+            return null;
+        }
+
+        JsonObject properties = new JsonObject();
+        JsonArray required = new JsonArray();
+        for (DevConsoleOptionModel opt : options) {
+            JsonObject prop = buildSchema(opt);
+            if (opt.getDescription() != null) {
+                prop.put("description", opt.getDescription());
+            }
+            properties.put(opt.getName(), prop);
+            if (opt.isRequired()) {
+                required.add(opt.getName());
+            }
+        }
+
+        JsonObject schema = new JsonObject();
+        schema.put("type", "object");
+        schema.put("properties", properties);
+        if (!required.isEmpty()) {
+            schema.put("required", required);
+        }
+
+        JsonObject mediaType = new JsonObject();
+        mediaType.put("schema", schema);
+        JsonObject content = new JsonObject();
+        content.put("application/json", mediaType);
+        JsonObject requestBody = new JsonObject();
+        requestBody.put("content", content);
+        return requestBody;
+    }
+
+    private static JsonObject buildSchema(DevConsoleOptionModel opt) {
+        JsonObject schema = new JsonObject();
+        if (opt.getType() != null) {
+            schema.put("type", opt.getType());
+        }
+        if (opt.getDefaultValue() != null) {
+            schema.put("default", opt.resolveDefaultValue());
+        }
+        if (opt.getEnums() != null && !opt.getEnums().isEmpty()) {
+            schema.put("enum", new JsonArray(opt.getEnums()));
+        }
+        return schema;
+    }
+}
diff --git 
a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/JsonMapper.java
 
b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/JsonMapper.java
index 40723b4e4acb..46903a93bd7b 100644
--- 
a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/JsonMapper.java
+++ 
b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/JsonMapper.java
@@ -494,6 +494,7 @@ public final class JsonMapper {
         DevConsoleModel model = new DevConsoleModel();
         parseModel(mobj, model);
         model.setGroup(mobj.getString("group"));
+        model.setReadOnly(mobj.getBooleanOrDefault("readOnly", true));
         parseArtifact(mobj, model);
         JsonObject options = (JsonObject) obj.get("options");
         if (options != null) {
@@ -517,6 +518,7 @@ public final class JsonMapper {
         baseToJson(model, obj);
         artifactToJson(model, obj);
         obj.put("group", model.getGroup());
+        obj.put("readOnly", model.isReadOnly());
         obj.entrySet().removeIf(e -> e.getValue() == null);
         JsonObject wrapper = new JsonObject();
         wrapper.put("console", obj);
diff --git 
a/tooling/camel-tooling-model/src/test/java/org/apache/camel/tooling/model/DevConsoleOpenApiHelperTest.java
 
b/tooling/camel-tooling-model/src/test/java/org/apache/camel/tooling/model/DevConsoleOpenApiHelperTest.java
new file mode 100644
index 000000000000..f92b673b1227
--- /dev/null
+++ 
b/tooling/camel-tooling-model/src/test/java/org/apache/camel/tooling/model/DevConsoleOpenApiHelperTest.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.tooling.model;
+
+import java.util.List;
+
+import org.apache.camel.tooling.model.DevConsoleModel.DevConsoleOptionModel;
+import org.apache.camel.util.json.JsonObject;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * The unit test class for {@link DevConsoleOpenApiHelper}.
+ */
+class DevConsoleOpenApiHelperTest {
+
+    private static DevConsoleOptionModel option(String name, String type, 
boolean required) {
+        DevConsoleOptionModel option = new DevConsoleOptionModel();
+        option.setName(name);
+        option.setType(type);
+        option.setRequired(required);
+        option.setDescription("The " + name);
+        return option;
+    }
+
+    @Test
+    void readOnlyConsoleWithOptionsBuildsGetWithParameters() {
+        DevConsoleModel model = new DevConsoleModel();
+        model.setName("route");
+        model.setTitle("Route");
+        model.setDescription("Route information");
+        model.setReadOnly(true);
+        model.addOption(option("filter", "string", false));
+        model.addOption(option("limit", "integer", false));
+
+        JsonObject pathItem = DevConsoleOpenApiHelper.buildPathItem(model);
+
+        assertNull(pathItem.get("post"));
+        JsonObject get = pathItem.getJsonObject("get");
+        assertNotNull(get);
+        assertEquals("route", get.getString("operationId"));
+        assertNull(get.get("requestBody"));
+        var parameters = get.getCollection("parameters");
+        assertEquals(2, parameters.size());
+    }
+
+    @Test
+    void mutatingConsoleWithOptionsBuildsPostWithRequestBody() {
+        DevConsoleModel model = new DevConsoleModel();
+        model.setName("route");
+        model.setTitle("Route");
+        model.setDescription("Route information");
+        model.setReadOnly(false);
+        model.addOption(option("action", "string", true));
+
+        JsonObject pathItem = DevConsoleOpenApiHelper.buildPathItem(model);
+
+        assertNull(pathItem.get("get"));
+        JsonObject post = pathItem.getJsonObject("post");
+        assertNotNull(post);
+        assertNull(post.get("parameters"));
+        JsonObject requestBody = post.getJsonObject("requestBody");
+        assertNotNull(requestBody);
+        JsonObject schema = 
requestBody.getJsonObject("content").getJsonObject("application/json").getJsonObject("schema");
+        assertTrue(schema.getCollection("required").contains("action"));
+    }
+
+    @Test
+    void consoleWithoutOptionsHasNeitherParametersNorRequestBody() {
+        DevConsoleModel model = new DevConsoleModel();
+        model.setName("context");
+        model.setTitle("CamelContext");
+        model.setDescription("Overall information about the CamelContext");
+        model.setReadOnly(true);
+
+        JsonObject pathItem = DevConsoleOpenApiHelper.buildPathItem(model);
+
+        JsonObject get = pathItem.getJsonObject("get");
+        assertNotNull(get);
+        assertNull(get.get("parameters"));
+        assertNull(get.get("requestBody"));
+    }
+
+    @Test
+    void openApiDocumentContainsOnePathPerConsoleSortedByName() {
+        DevConsoleModel context = new DevConsoleModel();
+        context.setName("context");
+        context.setTitle("CamelContext");
+        context.setDescription("Overall information about the CamelContext");
+        context.setReadOnly(true);
+
+        DevConsoleModel route = new DevConsoleModel();
+        route.setName("route");
+        route.setTitle("Route");
+        route.setDescription("Route information");
+        route.setReadOnly(false);
+
+        JsonObject doc = 
DevConsoleOpenApiHelper.buildOpenApiDocument(List.of(route, context), 
"4.23.0-SNAPSHOT");
+
+        assertEquals("3.0.3", doc.getString("openapi"));
+        assertEquals("4.23.0-SNAPSHOT", 
doc.getJsonObject("info").getString("version"));
+        JsonObject paths = doc.getJsonObject("paths");
+        
assertNotNull(paths.getJsonObject("/q/dev/context").getJsonObject("get"));
+        
assertNotNull(paths.getJsonObject("/q/dev/route").getJsonObject("post"));
+        assertFalse(paths.containsKey("/q/dev/missing"));
+    }
+}
diff --git 
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
index 7ce21e3fa9c2..09c32609049b 100644
--- 
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
+++ 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
@@ -48,6 +48,7 @@ import org.apache.camel.tooling.model.BaseOptionModel;
 import org.apache.camel.tooling.model.ComponentModel;
 import org.apache.camel.tooling.model.DataFormatModel;
 import org.apache.camel.tooling.model.DevConsoleModel;
+import org.apache.camel.tooling.model.DevConsoleOpenApiHelper;
 import org.apache.camel.tooling.model.EipModel;
 import org.apache.camel.tooling.model.JsonMapper;
 import org.apache.camel.tooling.model.LanguageModel;
@@ -59,6 +60,8 @@ import org.apache.camel.tooling.model.TransformerModel;
 import org.apache.camel.tooling.util.FileUtil;
 import org.apache.camel.tooling.util.PackageHelper;
 import org.apache.camel.tooling.util.Strings;
+import org.apache.camel.util.json.JsonObject;
+import org.apache.camel.util.json.Jsoner;
 import org.apache.maven.plugin.AbstractMojo;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.MojoFailureException;
@@ -899,6 +902,15 @@ public class PrepareCatalogMojo extends AbstractMojo {
                 = 
jsonFiles.stream().map(PrepareCatalogMojo::asComponentName).collect(Collectors.toCollection(TreeSet::new));
         FileUtil.updateFile(all, String.join("\n", consoleNames) + "\n");
 
+        // build and write a single consolidated OpenAPI document describing 
every dev console
+        List<DevConsoleModel> models = jsonFiles.stream()
+                .map(p -> (DevConsoleModel) allModels.get(p))
+                .collect(Collectors.toList());
+        JsonObject openApi = 
DevConsoleOpenApiHelper.buildOpenApiDocument(models, project.getVersion());
+        Path openApiFile = 
consolesOutDir.resolve("../dev-consoles-openapi.json");
+        FileUtil.updateFile(openApiFile, Jsoner.prettyPrint(openApi.toJson()) 
+ "\n");
+        getLog().info("Generated dev-consoles-openapi.json containing " + 
models.size() + " Camel dev console paths");
+
         printConsolesReport(jsonFiles, duplicateJsonFiles);
 
         return consoleNames;

Reply via email to