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

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

commit d287590b6da66f61048b9cc73a9af5268142908d
Author: Claus Ibsen <[email protected]>
AuthorDate: Sat Aug 29 12:46:16 2026 +0200

    CAMEL-24514: camel-console - Generate GET instead of POST for read-only dev 
consoles in OpenAPI spec
    
    ApiDevConsole previously advertised every dev console as a POST operation, 
even
    though /q/dev was originally GET-only and most consoles are safe, read-only
    introspection endpoints. Add a DevConsole.isReadOnly() SPI method (default 
true)
    so each console declares whether it mutates runtime state; ApiDevConsole now
    generates a GET operation with query parameters for read-only consoles, and
    keeps POST with a JSON requestBody only for the consoles that need an 
arbitrary
    body (eval-language, send, sql-query) or that mutate state (route, 
route-group,
    processor, trace, jfr-memory-leak, receive, debug, heap-dump, reload, and
    camel-jfr's jfr console).
    
    Co-Authored-By: Claude Sonnet 5 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../camel/runtime/jfr/CamelJfrDevConsole.java      |   5 +
 .../camel/runtime/jfr/CamelJfrDevConsoleTest.java  |   6 +
 .../java/org/apache/camel/console/DevConsole.java  |  13 ++
 .../apache/camel/impl/console/ApiDevConsole.java   | 172 ++++++++++++++-------
 .../apache/camel/impl/console/DebugDevConsole.java |   5 +
 .../camel/impl/console/EvalLanguageDevConsole.java |   5 +
 .../camel/impl/console/HeapDumpDevConsole.java     |   5 +
 .../impl/console/JfrMemoryLeakDevConsole.java      |   5 +
 .../camel/impl/console/ProcessorDevConsole.java    |   5 +
 .../camel/impl/console/ReceiveDevConsole.java      |   5 +
 .../camel/impl/console/ReloadDevConsole.java       |   5 +
 .../apache/camel/impl/console/RouteDevConsole.java |   5 +
 .../camel/impl/console/RouteGroupDevConsole.java   |   5 +
 .../apache/camel/impl/console/SendDevConsole.java  |   5 +
 .../camel/impl/console/SqlQueryDevConsole.java     |   5 +
 .../apache/camel/impl/console/TraceDevConsole.java |   5 +
 .../camel/impl/console/ApiDevConsoleTest.java      |  69 +++++++++
 17 files changed, 271 insertions(+), 54 deletions(-)

diff --git 
a/components/camel-jfr/src/main/java/org/apache/camel/runtime/jfr/CamelJfrDevConsole.java
 
b/components/camel-jfr/src/main/java/org/apache/camel/runtime/jfr/CamelJfrDevConsole.java
index 3aeff394ee6c..7b57a2cdc4ef 100644
--- 
a/components/camel-jfr/src/main/java/org/apache/camel/runtime/jfr/CamelJfrDevConsole.java
+++ 
b/components/camel-jfr/src/main/java/org/apache/camel/runtime/jfr/CamelJfrDevConsole.java
@@ -83,6 +83,11 @@ public class CamelJfrDevConsole extends AbstractDevConsole {
               "Status and live control of camel-jfr runtime instrumentation");
     }
 
+    @Override
+    public boolean isReadOnly() {
+        return false;
+    }
+
     private boolean isInstrumentationRegistered() {
         CamelContext ctx = getCamelContext();
         if (ctx == null) {
diff --git 
a/components/camel-jfr/src/test/java/org/apache/camel/runtime/jfr/CamelJfrDevConsoleTest.java
 
b/components/camel-jfr/src/test/java/org/apache/camel/runtime/jfr/CamelJfrDevConsoleTest.java
index cabb6dbe087e..ce49030870aa 100644
--- 
a/components/camel-jfr/src/test/java/org/apache/camel/runtime/jfr/CamelJfrDevConsoleTest.java
+++ 
b/components/camel-jfr/src/test/java/org/apache/camel/runtime/jfr/CamelJfrDevConsoleTest.java
@@ -62,6 +62,12 @@ class CamelJfrDevConsoleTest extends CamelTestSupport {
         return recording;
     }
 
+    @Test
+    void isNotReadOnly() {
+        // the console can enable/disable JFR events and trigger snapshots, so 
it must not be advertised as safe
+        assertThat(resolveConsole(context).isReadOnly()).isFalse();
+    }
+
     @Test
     void statusReportsNotRegisteredByDefault() {
         // camel-jfr is on the classpath, but its runtime instrumentation is 
opt-in, so merely having the
diff --git 
a/core/camel-api/src/main/java/org/apache/camel/console/DevConsole.java 
b/core/camel-api/src/main/java/org/apache/camel/console/DevConsole.java
index 087fd269a6b7..ccda24bac038 100644
--- a/core/camel-api/src/main/java/org/apache/camel/console/DevConsole.java
+++ b/core/camel-api/src/main/java/org/apache/camel/console/DevConsole.java
@@ -62,6 +62,19 @@ public interface DevConsole {
      */
     boolean supportMediaType(MediaType mediaType);
 
+    /**
+     * Whether this console is read-only (safe, and does not change any 
runtime state).
+     * <p/>
+     * Consoles that mutate state (such as starting/stopping a route, sending 
a message, or triggering a heap dump) must
+     * override this method to return {@code false}.
+     *
+     * @return true if read-only (the default), false if invoking this console 
changes runtime state.
+     * @since  4.23
+     */
+    default boolean isReadOnly() {
+        return true;
+    }
+
     /**
      * Invokes and gets the output from this console.
      */
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 f3963069a2c6..2fe27561dda6 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
@@ -82,15 +82,24 @@ public class ApiDevConsole extends AbstractDevConsole {
 
             for (org.apache.camel.console.DevConsole console : consoles) {
                 String id = console.getId();
+                boolean readOnly = console.isReadOnly();
+
                 JsonObject pathItem = new JsonObject();
-                JsonObject post = new JsonObject();
-                post.put("summary", console.getDisplayName());
-                post.put("description", console.getDescription());
-                post.put("operationId", id);
-
-                JsonObject requestBody = buildConsoleRequestBody(id);
-                if (requestBody != null) {
-                    post.put("requestBody", requestBody);
+                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();
@@ -100,9 +109,9 @@ public class ApiDevConsole extends AbstractDevConsole {
                 responseContent.put("application/json", new JsonObject());
                 ok.put("content", responseContent);
                 responses.put("200", ok);
-                post.put("responses", responses);
+                operation.put("responses", responses);
 
-                pathItem.put("post", post);
+                pathItem.put(readOnly ? "get" : "post", operation);
                 paths.put("/q/dev/" + id, pathItem);
             }
         }
@@ -111,7 +120,12 @@ public class ApiDevConsole extends AbstractDevConsole {
         return Jsoner.prettyPrint(root.toJson());
     }
 
-    private JsonObject buildConsoleRequestBody(String consoleId) {
+    /**
+     * 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
+     */
+    private JsonObject loadConsoleOptions(String consoleId) {
         try {
             String json = ((CatalogCamelContext) getCamelContext())
                     .getDevConsoleParameterJsonSchema(consoleId);
@@ -126,56 +140,106 @@ public class ApiDevConsole extends AbstractDevConsole {
             if (!(optionsObj instanceof JsonObject opts) || opts.isEmpty()) {
                 return null;
             }
+            return opts;
+        } catch (Exception e) {
+            // ignore
+            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);
+    private JsonObject buildConsoleRequestBody(String consoleId) {
+        JsonObject opts = loadConsoleOptions(consoleId);
+        if (opts == null) {
+            return null;
+        }
 
-                Boolean req = opt.getBoolean("required");
-                if (req != null && req) {
-                    required.add(name);
-                }
+        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);
 
-            JsonObject schema = new JsonObject();
-            schema.put("type", "object");
-            schema.put("properties", properties);
-            if (!required.isEmpty()) {
-                schema.put("required", required);
+            Boolean req = opt.getBoolean("required");
+            if (req != null && req) {
+                required.add(name);
             }
+        }
 
-            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;
-        } catch (Exception e) {
-            // ignore
+        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);
+        }
+        return parameters.isEmpty() ? null : parameters;
     }
 }
diff --git 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/DebugDevConsole.java
 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/DebugDevConsole.java
index 211598e215ed..decaa2f7e681 100644
--- 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/DebugDevConsole.java
+++ 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/DebugDevConsole.java
@@ -61,6 +61,11 @@ public class DebugDevConsole extends AbstractDevConsole {
         super("camel", "debug", "Debug", "Camel route debugger");
     }
 
+    @Override
+    public boolean isReadOnly() {
+        return false;
+    }
+
     @Override
     protected String doCallText(Map<String, Object> options) {
         String command = optionString(options, COMMAND);
diff --git 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/EvalLanguageDevConsole.java
 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/EvalLanguageDevConsole.java
index 2eeea51acd74..aed61a0f7e2d 100644
--- 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/EvalLanguageDevConsole.java
+++ 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/EvalLanguageDevConsole.java
@@ -55,6 +55,11 @@ public class EvalLanguageDevConsole extends 
AbstractDevConsole {
         super("camel", "eval-language", "Evaluate Language", "Evaluate 
Language and display result");
     }
 
+    @Override
+    public boolean isReadOnly() {
+        return false;
+    }
+
     @Override
     protected String doCallText(Map<String, Object> options) {
         StringBuilder sb = new StringBuilder();
diff --git 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/HeapDumpDevConsole.java
 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/HeapDumpDevConsole.java
index 9351218b149a..5f208ba50b7d 100644
--- 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/HeapDumpDevConsole.java
+++ 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/HeapDumpDevConsole.java
@@ -51,6 +51,11 @@ public class HeapDumpDevConsole extends AbstractDevConsole {
         super("jvm", "heap-dump", "Heap Dump", "Write a heap dump (.hprof) 
file for deep memory analysis");
     }
 
+    @Override
+    public boolean isReadOnly() {
+        return false;
+    }
+
     @Override
     protected String doCallText(Map<String, Object> options) {
         JsonObject json = doCallJson(options);
diff --git 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/JfrMemoryLeakDevConsole.java
 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/JfrMemoryLeakDevConsole.java
index 705b375790de..1ebdcdcbb319 100644
--- 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/JfrMemoryLeakDevConsole.java
+++ 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/JfrMemoryLeakDevConsole.java
@@ -99,6 +99,11 @@ public class JfrMemoryLeakDevConsole extends 
AbstractDevConsole {
               "JFR-based old object sampling for memory leak diagnosis");
     }
 
+    @Override
+    public boolean isReadOnly() {
+        return false;
+    }
+
     @Override
     protected String doCallText(Map<String, Object> options) {
         JsonObject json = doCallJson(options);
diff --git 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/ProcessorDevConsole.java
 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/ProcessorDevConsole.java
index a1c0b8baf57a..dd830b513a8a 100644
--- 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/ProcessorDevConsole.java
+++ 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/ProcessorDevConsole.java
@@ -64,6 +64,11 @@ public class ProcessorDevConsole extends AbstractDevConsole {
         super("camel", "processor", "Processor", "Processor information");
     }
 
+    @Override
+    public boolean isReadOnly() {
+        return false;
+    }
+
     @Override
     protected String doCallText(Map<String, Object> options) {
         String action = optionString(options, ACTION);
diff --git 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/ReceiveDevConsole.java
 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/ReceiveDevConsole.java
index 71e8da82d952..32d935674459 100644
--- 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/ReceiveDevConsole.java
+++ 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/ReceiveDevConsole.java
@@ -85,6 +85,11 @@ public class ReceiveDevConsole extends AbstractDevConsole {
         super("camel", "receive", "Camel Receive", "Consume messages from 
endpoints");
     }
 
+    @Override
+    public boolean isReadOnly() {
+        return false;
+    }
+
     public int getCapacity() {
         return capacity;
     }
diff --git 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/ReloadDevConsole.java
 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/ReloadDevConsole.java
index 1507da680973..582badf694e2 100644
--- 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/ReloadDevConsole.java
+++ 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/ReloadDevConsole.java
@@ -49,6 +49,11 @@ public class ReloadDevConsole extends AbstractDevConsole {
         super("camel", "reload", "Reload", "Console for reloading running 
Camel");
     }
 
+    @Override
+    public boolean isReadOnly() {
+        return false;
+    }
+
     protected String doCallText(Map<String, Object> options) {
         boolean trigger = optionBoolean(options, RELOAD, false);
         boolean wait = optionBoolean(options, RELOAD_WAIT, false);
diff --git 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDevConsole.java
 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDevConsole.java
index 5e77d6f69f5f..826b1a8514f4 100644
--- 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDevConsole.java
+++ 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDevConsole.java
@@ -70,6 +70,11 @@ public class RouteDevConsole extends AbstractDevConsole {
         super("camel", "route", "Route", "Route information");
     }
 
+    @Override
+    public boolean isReadOnly() {
+        return false;
+    }
+
     @Override
     protected String doCallText(Map<String, Object> options) {
         String action = optionString(options, ACTION);
diff --git 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteGroupDevConsole.java
 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteGroupDevConsole.java
index 80984b9fd8a5..b05e1de71819 100644
--- 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteGroupDevConsole.java
+++ 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteGroupDevConsole.java
@@ -62,6 +62,11 @@ public class RouteGroupDevConsole extends AbstractDevConsole 
{
         super("camel", "route-group", "Route Group", "Route Group 
information");
     }
 
+    @Override
+    public boolean isReadOnly() {
+        return false;
+    }
+
     @Override
     protected String doCallText(Map<String, Object> options) {
         String action = optionString(options, ACTION);
diff --git 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/SendDevConsole.java
 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/SendDevConsole.java
index 8fd1c5e39034..c75f6b9db08b 100644
--- 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/SendDevConsole.java
+++ 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/SendDevConsole.java
@@ -87,6 +87,11 @@ public class SendDevConsole extends AbstractDevConsole {
         super("camel", "send", "Camel Send", "Send messages to endpoints");
     }
 
+    @Override
+    public boolean isReadOnly() {
+        return false;
+    }
+
     @Override
     protected void doInit() throws Exception {
         super.doInit();
diff --git 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/SqlQueryDevConsole.java
 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/SqlQueryDevConsole.java
index 914d1de0a948..1b92020f9021 100644
--- 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/SqlQueryDevConsole.java
+++ 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/SqlQueryDevConsole.java
@@ -88,6 +88,11 @@ public class SqlQueryDevConsole extends AbstractDevConsole {
         super("camel", "sql-query", "SQL Query", "Execute SQL queries on 
DataSource beans");
     }
 
+    @Override
+    public boolean isReadOnly() {
+        return false;
+    }
+
     public int getDefaultMaxRows() {
         return defaultMaxRows;
     }
diff --git 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/TraceDevConsole.java
 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/TraceDevConsole.java
index d1aeda3d3d48..7782ea4ed879 100644
--- 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/TraceDevConsole.java
+++ 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/TraceDevConsole.java
@@ -51,6 +51,11 @@ public class TraceDevConsole extends AbstractDevConsole {
         super("camel", "trace", "Camel Tracing", "Trace routed messages");
     }
 
+    @Override
+    public boolean isReadOnly() {
+        return false;
+    }
+
     public int getCapacity() {
         return capacity;
     }
diff --git 
a/core/camel-console/src/test/java/org/apache/camel/impl/console/ApiDevConsoleTest.java
 
b/core/camel-console/src/test/java/org/apache/camel/impl/console/ApiDevConsoleTest.java
new file mode 100644
index 000000000000..0fbab572ad9b
--- /dev/null
+++ 
b/core/camel-console/src/test/java/org/apache/camel/impl/console/ApiDevConsoleTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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.impl.console;
+
+import org.apache.camel.console.DevConsole;
+import org.apache.camel.console.DevConsoleRegistry;
+import org.apache.camel.util.json.JsonObject;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ApiDevConsoleTest extends AbstractDevConsoleTest {
+
+    private JsonObject openApiPaths() {
+        DevConsoleRegistry dcr = 
context.getCamelContextExtension().getContextPlugin(DevConsoleRegistry.class);
+        dcr.loadDevConsoles();
+
+        DevConsole con = assertConsoleExists("api", "camel");
+        JsonObject root = callJson(con);
+        JsonObject paths = root.getJsonObject("paths");
+        assertThat(paths).isNotNull();
+        return paths;
+    }
+
+    @Test
+    public void testReadOnlyConsoleUsesGet() {
+        JsonObject paths = openApiPaths();
+
+        JsonObject contextPath = paths.getJsonObject("/q/dev/context");
+        assertThat(contextPath).as("context console path should 
exist").isNotNull();
+        assertThat(contextPath.getJsonObject("get")).as("context console 
should be declared as GET").isNotNull();
+        assertThat(contextPath.getJsonObject("post")).as("context console 
should not be declared as POST").isNull();
+    }
+
+    @Test
+    public void testMutatingConsoleUsesPost() {
+        JsonObject paths = openApiPaths();
+
+        JsonObject routePath = paths.getJsonObject("/q/dev/route");
+        assertThat(routePath).as("route console path should 
exist").isNotNull();
+        assertThat(routePath.getJsonObject("get")).as("route console should 
not be declared as GET").isNull();
+
+        JsonObject post = routePath.getJsonObject("post");
+        assertThat(post).as("route console should be declared as 
POST").isNotNull();
+        assertThat(post.get("requestBody")).as("route console POST should 
carry a requestBody").isNotNull();
+    }
+
+    @Test
+    public void testIsReadOnlyDefaults() {
+        assertThat(new ContextDevConsole().isReadOnly()).isTrue();
+        assertThat(new RouteDevConsole().isReadOnly()).isFalse();
+        assertThat(new EvalLanguageDevConsole().isReadOnly()).isFalse();
+        assertThat(new SendDevConsole().isReadOnly()).isFalse();
+    }
+}

Reply via email to