Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add camel-console management endpoint #7005

Merged
merged 1 commit into from
Feb 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions docs/modules/ROOT/pages/reference/extensions/console.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,83 @@ Please refer to the above link for usage and configuration details.
ifeval::[{doc-show-user-guide-link} == true]
Check the xref:user-guide/index.adoc[User guide] for more information about writing Camel Quarkus applications.
endif::[]

[id="extensions-console-usage"]
== Usage
[id="extensions-console-usage-developer-console-endpoint"]
=== Developer console endpoint

To access the developer console, you must first enable it by adding configuration to `application.properties`.

[source,properties]
----
quarkus.camel.console.enabled=true
----

Alternatively you can use a `camel-main` configuration option.

[source,properties]
----
camel.main.dev-console-enabled=true
----

The console is then available at the following URL.

[source,text]
----
http://localhost:8080/q/camel/dev-console
----

You can then call a console by its id, such as `routes`:

[source,text]
----
http://localhost:8080/q/camel/dev-console/routes
----

[id="extensions-console-usage-exposing-the-developer-console-in-prod-mode"]
=== Exposing the developer console in prod mode

By default, the console is only exposed in dev and test modes. To expose the console in prod mode, add the following configuration to `application.properties`.

[source,properties]
----
quarkus.camel.console.exposure-mode=ALL
----

See the configuration overview below for further details about `exposure-mode`.


[id="extensions-console-additional-camel-quarkus-configuration"]
== Additional Camel Quarkus configuration

[width="100%",cols="80,5,15",options="header"]
|===
| Configuration property | Type | Default


|icon:lock[title=Fixed at build time] [[quarkus.camel.console.enabled]]`link:#quarkus.camel.console.enabled[quarkus.camel.console.enabled]`

Whether the Camel developer console is enabled.
| `boolean`
| `false`

|icon:lock[title=Fixed at build time] [[quarkus.camel.console.path]]`link:#quarkus.camel.console.path[quarkus.camel.console.path]`

The context path under which the Camel developer console is deployed (default /q/camel/dev-console).
| `string`
| `camel/dev-console`

|icon:lock[title=Fixed at build time] [[quarkus.camel.console.exposure-mode]]`link:#quarkus.camel.console.exposure-mode[quarkus.camel.console.exposure-mode]`

The modes in which the Camel developer console is available. The default {@code dev-test} enables the developer
console only in dev mode and test modes.
A value of {@code all} enables agent discovery in dev, test and prod modes. Setting the value to {@code none} will
not expose the developer console HTTP endpoint.
| `all`, `dev-test`, `none`
| `dev-test`
|===

[.configuration-legend]
{doc-link-icon-lock}[title=Fixed at build time] Configuration property fixed at build time. All other configuration properties are overridable at runtime.

9 changes: 9 additions & 0 deletions extensions-jvm/console/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
<name>Camel Quarkus :: Console :: Deployment</name>

<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-vertx-http-deployment</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-core-deployment</artifactId>
Expand All @@ -44,6 +48,11 @@
<artifactId>quarkus-junit5-internal</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-stub</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,33 @@
*/
package org.apache.camel.quarkus.component.console.deployment;

import java.util.function.BooleanSupplier;
import java.util.function.Consumer;

import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.BuildSteps;
import io.quarkus.deployment.annotations.ExecutionTime;
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.pkg.steps.NativeOrNativeSourcesBuild;
import io.quarkus.runtime.LaunchMode;
import io.quarkus.vertx.http.deployment.NonApplicationRootPathBuildItem;
import io.quarkus.vertx.http.deployment.RouteBuildItem;
import io.vertx.core.Handler;
import io.vertx.ext.web.Route;
import io.vertx.ext.web.RoutingContext;
import org.apache.camel.quarkus.component.console.CamelConsoleConfig;
import org.apache.camel.quarkus.component.console.CamelConsoleRecorder;
import org.apache.camel.quarkus.core.JvmOnlyRecorder;
import org.apache.camel.quarkus.core.deployment.spi.CamelContextBuildItem;
import org.apache.camel.quarkus.core.deployment.spi.CamelServiceDestination;
import org.apache.camel.quarkus.core.deployment.spi.CamelServicePatternBuildItem;
import org.eclipse.microprofile.config.ConfigProvider;
import org.jboss.logging.Logger;

@BuildSteps(onlyIf = ConsoleProcessor.CamelConsoleEnabled.class)
class ConsoleProcessor {

private static final Logger LOG = Logger.getLogger(ConsoleProcessor.class);
private static final String FEATURE = "camel-console";

Expand All @@ -42,6 +57,41 @@ CamelServicePatternBuildItem devConsoleServicePattern() {
"META-INF/services/org/apache/camel/dev-console/*");
}

@BuildStep
@Record(ExecutionTime.STATIC_INIT)
void initDevConsoleRegistry(
CamelContextBuildItem camelContext,
CamelConsoleRecorder recorder) {
recorder.initDevConsoleRegistry(camelContext.getCamelContext());
}

@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
void createManagementRoute(
CamelContextBuildItem camelContext,
NonApplicationRootPathBuildItem nonApplicationRootPathBuildItem,
BuildProducer<RouteBuildItem> routes,
CamelConsoleConfig config,
CamelConsoleRecorder recorder) {

if (canExposeManagementEndpoint(config)) {
Consumer<Route> route = recorder.route();
Handler<RoutingContext> handler = recorder.getHandler(camelContext.getCamelContext());

routes.produce(nonApplicationRootPathBuildItem.routeBuilder()
.management()
.routeFunction(config.path(), route)
.handler(handler)
.build());

routes.produce(nonApplicationRootPathBuildItem.routeBuilder()
.management()
.routeFunction(config.path() + "/:id", route)
.handler(handler)
.build());
}
}

/**
* Remove this once this extension starts supporting the native mode.
*/
Expand All @@ -51,4 +101,21 @@ void warnJvmInNative(JvmOnlyRecorder recorder) {
JvmOnlyRecorder.warnJvmInNative(LOG, FEATURE); // warn at build time
recorder.warnJvmInNative(FEATURE); // warn at runtime
}

private static boolean canExposeManagementEndpoint(CamelConsoleConfig config) {
return (LaunchMode.current().isDevOrTest()
&& config.exposureMode() == CamelConsoleConfig.ExposureMode.DEV_TEST)
|| config.exposureMode().equals(CamelConsoleConfig.ExposureMode.ALL);
}

static final class CamelConsoleEnabled implements BooleanSupplier {
CamelConsoleConfig config;

@Override
public boolean getAsBoolean() {
return config.enabled() || ConfigProvider.getConfig()
.getOptionalValue("camel.main.dev-console-enabled", Boolean.class)
.orElse(false);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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.quarkus.component.console;

import io.quarkus.test.QuarkusUnitTest;
import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

class ConsoleDisabledTest {
@RegisterExtension
static final QuarkusUnitTest CONFIG = new QuarkusUnitTest().withEmptyApplication();

@Test
void managementEndpointDisabled() {
RestAssured.get("/q/camel/dev-console")
.then()
.statusCode(404);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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.quarkus.component.console;

import io.quarkus.test.QuarkusUnitTest;
import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

class ConsoleEnabledWithCamelMainPropertyTest {
@RegisterExtension
static final QuarkusUnitTest CONFIG = new QuarkusUnitTest()
.withEmptyApplication()
.overrideConfigKey("camel.main.dev-console-enabled", "true");

@Test
void managementEndpointEnabled() {
RestAssured.get("/q/camel/dev-console")
.then()
.statusCode(200);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* 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.quarkus.component.console;

import io.quarkus.test.QuarkusUnitTest;
import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

class ConsoleManagementEndpointCustomPathTest {
@RegisterExtension
static final QuarkusUnitTest CONFIG = new QuarkusUnitTest()
.withEmptyApplication()
.overrideConfigKey("quarkus.camel.console.enabled", "true")
.overrideConfigKey("quarkus.camel.console.path", "camel/other");

@Test
void alternateManagementEndpointPath() {
RestAssured.get("/q/camel/other")
.then()
.statusCode(200);
}

@Test
void alternateManagementEndpointPathWithId() {
RestAssured.get("/q/camel/other/context")
.then()
.statusCode(200);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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.quarkus.component.console;

import io.quarkus.test.QuarkusUnitTest;
import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

class ConsoleNotExposedTest {
@RegisterExtension
static final QuarkusUnitTest CONFIG = new QuarkusUnitTest()
.withEmptyApplication()
.overrideConfigKey("quarkus.camel.console.exposure-mode", "none");

@Test
void managementEndpointNotExposed() {
RestAssured.get("/q/camel/dev-console")
.then()
.statusCode(404);
}
}
4 changes: 4 additions & 0 deletions extensions-jvm/console/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
</properties>

<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-vertx-http</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-core</artifactId>
Expand Down
Loading