This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 89049d9ebda CAMEL-18425: camel-cli - Make regular Camel applications
work with Camel CLI
89049d9ebda is described below
commit 89049d9ebdac689188c44ff163ab27ddd03d3a1d
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Aug 25 19:35:56 2022 +0200
CAMEL-18425: camel-cli - Make regular Camel applications work with Camel CLI
---
bom/camel-bom/pom.xml | 5 +
.../org/apache/camel/catalog/others.properties | 1 +
.../apache/camel/catalog/others/cli-connector.json | 15 ++
.../org/apache/camel/ExtendedCamelContext.java | 11 ++
.../org/apache/camel/spi/CliConnectorFactory.java | 69 +++++++
.../camel/impl/engine/AbstractCamelContext.java | 30 +++
.../camel/impl/engine/SimpleCamelContext.java | 12 ++
.../camel/impl/ExtendedCamelContextConfigurer.java | 6 +
.../camel/impl/lw/LightweightCamelContext.java | 11 ++
.../impl/lw/LightweightRuntimeCamelContext.java | 13 ++
.../camel/main/DefaultConfigurationConfigurer.java | 5 +
docs/components/modules/others/nav.adoc | 1 +
.../modules/others/pages/cli-connector.adoc | 1 +
dsl/camel-cli-connector/pom.xml | 129 +++++++++++++
.../org/apache/camel/cli-connector-factory | 2 +
.../services/org/apache/camel/other.properties | 7 +
.../src/generated/resources/cli-connector.json | 15 ++
.../src/main/docs/cli-connector.adoc | 27 +++
.../cli/connector/DefaultCliConnectorFactory.java | 71 +++++++
.../camel/cli/connector/LocalCliConnector.java | 206 +++++++++++++++++++++
dsl/camel-jbang/camel-jbang-core/pom.xml | 4 +
.../apache/camel/dsl/jbang/core/commands/Run.java | 77 --------
.../core/commands/process/CamelContextStatus.java | 21 ++-
.../jbang/core/commands/process/ListProcess.java | 2 +
.../core/commands/process/ProcessBaseCommand.java | 43 ++++-
dsl/pom.xml | 1 +
parent/pom.xml | 5 +
27 files changed, 710 insertions(+), 80 deletions(-)
diff --git a/bom/camel-bom/pom.xml b/bom/camel-bom/pom.xml
index 8ddddd276b7..092e662202e 100644
--- a/bom/camel-bom/pom.xml
+++ b/bom/camel-bom/pom.xml
@@ -436,6 +436,11 @@
<artifactId>camel-chunk</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-cli-connector</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-cloud</artifactId>
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others.properties
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others.properties
index af396b27e3c..22bae335791 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others.properties
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others.properties
@@ -4,6 +4,7 @@ caffeine-lrucache
cdi
cdi-jta
cdi-main
+cli-connector
cloud
cloudevents
cluster
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others/cli-connector.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others/cli-connector.json
new file mode 100644
index 00000000000..93654b1747b
--- /dev/null
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others/cli-connector.json
@@ -0,0 +1,15 @@
+{
+ "other": {
+ "kind": "other",
+ "name": "cli-connector",
+ "title": "CLI Connector",
+ "description": "Runtime adapter connecting with Camel CLI",
+ "deprecated": false,
+ "firstVersion": "3.19.0",
+ "label": "tooling",
+ "supportLevel": "Preview",
+ "groupId": "org.apache.camel",
+ "artifactId": "camel-cli-connector",
+ "version": "3.19.0-SNAPSHOT"
+ }
+}
diff --git
a/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java
b/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java
index c7f4ceb0d5e..bcbec2d9f94 100644
--- a/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java
+++ b/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java
@@ -32,6 +32,7 @@ import org.apache.camel.spi.BeanProxyFactory;
import org.apache.camel.spi.BootstrapCloseable;
import org.apache.camel.spi.CamelBeanPostProcessor;
import org.apache.camel.spi.CamelDependencyInjectionAnnotationFactory;
+import org.apache.camel.spi.CliConnectorFactory;
import org.apache.camel.spi.ComponentNameResolver;
import org.apache.camel.spi.ComponentResolver;
import org.apache.camel.spi.ConfigurerResolver;
@@ -789,6 +790,16 @@ public interface ExtendedCamelContext extends CamelContext
{
*/
void setStartupStepRecorder(StartupStepRecorder startupStepRecorder);
+ /**
+ * Gets the {@link CliConnectorFactory} (optional).
+ */
+ CliConnectorFactory getCliConnectorFactory();
+
+ /**
+ * Sets the {@link CliConnectorFactory} to use.
+ */
+ void setCliConnectorFactory(CliConnectorFactory cliConnectorFactory);
+
/**
* Internal API for adding routes. Do not use this as end user.
*/
diff --git
a/core/camel-api/src/main/java/org/apache/camel/spi/CliConnectorFactory.java
b/core/camel-api/src/main/java/org/apache/camel/spi/CliConnectorFactory.java
new file mode 100644
index 00000000000..5ca9212992f
--- /dev/null
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/CliConnectorFactory.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.spi;
+
+import org.apache.camel.Service;
+
+/**
+ * Factory for creating connector to CLI tooling.
+ * <p/>
+ * Such as a local connector that allows Camel CLI to manage local running
Camel integrations.
+ */
+public interface CliConnectorFactory {
+
+ /**
+ * Service factory key.
+ */
+ String FACTORY = "cli-connector-factory";
+
+ /**
+ * To enable CLI connector.
+ */
+ void setEnabled(boolean enabled);
+
+ /**
+ * Whether CLI connector is enabled.
+ */
+ boolean isEnabled();
+
+ /**
+ * What runtime platform is in use, such as camel-jbang,
camel-spring-boot, or camel-quarkus etc.
+ */
+ void setRuntime(String runtime);
+
+ /**
+ * What runtime platform is in use, such as camel-jbang,
camel-spring-boot, or camel-quarkus etc.
+ */
+ String getRuntime();
+
+ /**
+ * What runtime platform version is in use.
+ */
+ void setRuntimeVersion(String version);
+
+ /**
+ * What runtime platform version is in use.
+ */
+ String getRuntimeVersion();
+
+ /**
+ * Creates the connector which will be added as a {@link Service}
+ * to {@link org.apache.camel.CamelContext} as the lifecycle to start and
stop the connector.
+ */
+ Service createConnector();
+
+}
diff --git
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
index 81f97ad688b..ba50e572758 100644
---
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
+++
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
@@ -98,6 +98,7 @@ import org.apache.camel.spi.CamelContextTracker;
import org.apache.camel.spi.CamelDependencyInjectionAnnotationFactory;
import org.apache.camel.spi.CamelLogger;
import org.apache.camel.spi.ClassResolver;
+import org.apache.camel.spi.CliConnectorFactory;
import org.apache.camel.spi.ComponentNameResolver;
import org.apache.camel.spi.ComponentResolver;
import org.apache.camel.spi.ConfigurerResolver;
@@ -313,6 +314,7 @@ public abstract class AbstractCamelContext extends
BaseService
private volatile RestRegistryFactory restRegistryFactory;
private volatile RestRegistry restRegistry;
private volatile HeadersMapFactory headersMapFactory;
+ private volatile CliConnectorFactory cliConnectorFactory;
private volatile BeanProxyFactory beanProxyFactory;
private volatile BeanProcessorFactory beanProcessorFactory;
private volatile XMLRoutesDefinitionLoader xmlRoutesDefinitionLoader;
@@ -1525,6 +1527,10 @@ public abstract class AbstractCamelContext extends
BaseService
boolean forceStart, boolean useLifecycleStrategies)
throws Exception {
+ if (object == null) {
+ return;
+ }
+
// inject CamelContext
CamelContextAware.trySetCamelContext(object,
getCamelContextReference());
@@ -2858,6 +2864,11 @@ public abstract class AbstractCamelContext extends
BaseService
forceLazyInitialization();
+ CliConnectorFactory ccf = getCliConnectorFactory();
+ if (ccf != null && ccf.isEnabled()) {
+ LOG.info("Detected: {} JAR (Enabling Camel CLI Connector)", ccf);
+ addService(ccf.createConnector(), true);
+ }
addService(getManagementStrategy(), false);
lifecycleStrategies.sort(OrderedComparator.get());
ServiceHelper.initService(lifecycleStrategies);
@@ -5293,6 +5304,8 @@ public abstract class AbstractCamelContext extends
BaseService
protected abstract HeadersMapFactory createHeadersMapFactory();
+ protected abstract CliConnectorFactory createCliConnectorFactory();
+
protected abstract BeanProxyFactory createBeanProxyFactory();
protected abstract AnnotationBasedProcessorFactory
createAnnotationBasedProcessorFactory();
@@ -5365,6 +5378,23 @@ public abstract class AbstractCamelContext extends
BaseService
this.startupStepRecorder = startupStepRecorder;
}
+ @Override
+ public CliConnectorFactory getCliConnectorFactory() {
+ if (cliConnectorFactory == null) {
+ synchronized (lock) {
+ if (cliConnectorFactory == null) {
+ setCliConnectorFactory(createCliConnectorFactory());
+ }
+ }
+ }
+ return cliConnectorFactory;
+ }
+
+ @Override
+ public void setCliConnectorFactory(CliConnectorFactory
cliConnectorFactory) {
+ this.cliConnectorFactory = cliConnectorFactory;
+ }
+
@Deprecated
public enum Initialization {
Eager,
diff --git
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
index aaa24bbd5ae..0ea1c69b103 100644
---
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
+++
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
@@ -40,6 +40,7 @@ import org.apache.camel.spi.CamelBeanPostProcessor;
import org.apache.camel.spi.CamelContextNameStrategy;
import org.apache.camel.spi.CamelDependencyInjectionAnnotationFactory;
import org.apache.camel.spi.ClassResolver;
+import org.apache.camel.spi.CliConnectorFactory;
import org.apache.camel.spi.ComponentNameResolver;
import org.apache.camel.spi.ComponentResolver;
import org.apache.camel.spi.ConfigurerResolver;
@@ -409,6 +410,17 @@ public class SimpleCamelContext extends
AbstractCamelContext {
return result.orElseGet(DefaultHeadersMapFactory::new);
}
+ @Override
+ protected CliConnectorFactory createCliConnectorFactory() {
+ Optional<CliConnectorFactory> result = ResolverHelper.resolveService(
+ getCamelContextReference(),
+ getBootstrapFactoryFinder(),
+ CliConnectorFactory.FACTORY,
+ CliConnectorFactory.class);
+ // cli-connector is optional
+ return result.orElse(null);
+ }
+
@Override
protected BeanProxyFactory createBeanProxyFactory() {
Optional<BeanProxyFactory> result = ResolverHelper.resolveService(
diff --git
a/core/camel-core-engine/src/generated/java/org/apache/camel/impl/ExtendedCamelContextConfigurer.java
b/core/camel-core-engine/src/generated/java/org/apache/camel/impl/ExtendedCamelContextConfigurer.java
index e6fc9fb97c8..a721c3d8460 100644
---
a/core/camel-core-engine/src/generated/java/org/apache/camel/impl/ExtendedCamelContextConfigurer.java
+++
b/core/camel-core-engine/src/generated/java/org/apache/camel/impl/ExtendedCamelContextConfigurer.java
@@ -49,6 +49,8 @@ public class ExtendedCamelContextConfigurer extends
org.apache.camel.support.com
case "CaseInsensitiveHeaders":
target.setCaseInsensitiveHeaders(property(camelContext,
java.lang.Boolean.class, value)); return true;
case "classresolver":
case "ClassResolver": target.setClassResolver(property(camelContext,
org.apache.camel.spi.ClassResolver.class, value)); return true;
+ case "cliconnectorfactory":
+ case "CliConnectorFactory":
target.setCliConnectorFactory(property(camelContext,
org.apache.camel.spi.CliConnectorFactory.class, value)); return true;
case "componentnameresolver":
case "ComponentNameResolver":
target.setComponentNameResolver(property(camelContext,
org.apache.camel.spi.ComponentNameResolver.class, value)); return true;
case "componentresolver":
@@ -252,6 +254,8 @@ public class ExtendedCamelContextConfigurer extends
org.apache.camel.support.com
case "CaseInsensitiveHeaders": return java.lang.Boolean.class;
case "classresolver":
case "ClassResolver": return org.apache.camel.spi.ClassResolver.class;
+ case "cliconnectorfactory":
+ case "CliConnectorFactory": return
org.apache.camel.spi.CliConnectorFactory.class;
case "componentnameresolver":
case "ComponentNameResolver": return
org.apache.camel.spi.ComponentNameResolver.class;
case "componentresolver":
@@ -456,6 +460,8 @@ public class ExtendedCamelContextConfigurer extends
org.apache.camel.support.com
case "CaseInsensitiveHeaders": return
target.isCaseInsensitiveHeaders();
case "classresolver":
case "ClassResolver": return target.getClassResolver();
+ case "cliconnectorfactory":
+ case "CliConnectorFactory": return target.getCliConnectorFactory();
case "componentnameresolver":
case "ComponentNameResolver": return target.getComponentNameResolver();
case "componentresolver":
diff --git
a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java
b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java
index 5afb8d37a2e..9136cda08b2 100644
---
a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java
+++
b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java
@@ -83,6 +83,7 @@ import org.apache.camel.spi.CamelBeanPostProcessor;
import org.apache.camel.spi.CamelContextNameStrategy;
import org.apache.camel.spi.CamelDependencyInjectionAnnotationFactory;
import org.apache.camel.spi.ClassResolver;
+import org.apache.camel.spi.CliConnectorFactory;
import org.apache.camel.spi.ComponentNameResolver;
import org.apache.camel.spi.ComponentResolver;
import org.apache.camel.spi.ConfigurerResolver;
@@ -1781,6 +1782,16 @@ public class LightweightCamelContext implements
ExtendedCamelContext, CatalogCam
getExtendedCamelContext().setStartupStepRecorder(startupStepRecorder);
}
+ @Override
+ public CliConnectorFactory getCliConnectorFactory() {
+ return getExtendedCamelContext().getCliConnectorFactory();
+ }
+
+ @Override
+ public void setCliConnectorFactory(CliConnectorFactory
cliConnectorFactory) {
+ getExtendedCamelContext().setCliConnectorFactory(cliConnectorFactory);
+ }
+
@Override
public String getTestExcludeRoutes() {
return getExtendedCamelContext().getTestExcludeRoutes();
diff --git
a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java
b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java
index cdfa5250766..9d74aad134d 100644
---
a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java
+++
b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java
@@ -78,6 +78,7 @@ import org.apache.camel.spi.CamelBeanPostProcessor;
import org.apache.camel.spi.CamelContextNameStrategy;
import org.apache.camel.spi.CamelDependencyInjectionAnnotationFactory;
import org.apache.camel.spi.ClassResolver;
+import org.apache.camel.spi.CliConnectorFactory;
import org.apache.camel.spi.ComponentNameResolver;
import org.apache.camel.spi.ComponentResolver;
import org.apache.camel.spi.ConfigurerResolver;
@@ -181,6 +182,7 @@ public class LightweightRuntimeCamelContext implements
ExtendedCamelContext, Cat
private final CamelBeanPostProcessor beanPostProcessor;
private final CamelDependencyInjectionAnnotationFactory
dependencyInjectionAnnotationFactory;
private final HeadersMapFactory headersMapFactory;
+ private final CliConnectorFactory cliConnectorFactory;
private final ExchangeFactory exchangeFactory;
private final ExchangeFactoryManager exchangeFactoryManager;
private final ProcessorExchangeFactory processorExchangeFactory;
@@ -236,6 +238,7 @@ public class LightweightRuntimeCamelContext implements
ExtendedCamelContext, Cat
dependencyInjectionAnnotationFactory
=
context.adapt(ExtendedCamelContext.class).getDependencyInjectionAnnotationFactory();
headersMapFactory =
context.adapt(ExtendedCamelContext.class).getHeadersMapFactory();
+ cliConnectorFactory =
context.adapt(ExtendedCamelContext.class).getCliConnectorFactory();
exchangeFactory =
context.adapt(ExtendedCamelContext.class).getExchangeFactory();
exchangeFactoryManager =
context.adapt(ExtendedCamelContext.class).getExchangeFactoryManager();
modelineFactory =
context.adapt(ExtendedCamelContext.class).getModelineFactory();
@@ -1714,6 +1717,16 @@ public class LightweightRuntimeCamelContext implements
ExtendedCamelContext, Cat
throw new UnsupportedOperationException();
}
+ @Override
+ public CliConnectorFactory getCliConnectorFactory() {
+ return cliConnectorFactory;
+ }
+
+ @Override
+ public void setCliConnectorFactory(CliConnectorFactory
cliConnectorFactory) {
+ throw new UnsupportedOperationException();
+ }
+
@Override
public ExchangeFactory getExchangeFactory() {
return exchangeFactory;
diff --git
a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
index 18d076b6d5f..a1b431f763b 100644
---
a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
+++
b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
@@ -43,6 +43,7 @@ import org.apache.camel.model.ModelCamelContext;
import org.apache.camel.model.ModelLifecycleStrategy;
import org.apache.camel.spi.AsyncProcessorAwaitManager;
import org.apache.camel.spi.ClassResolver;
+import org.apache.camel.spi.CliConnectorFactory;
import org.apache.camel.spi.Debugger;
import org.apache.camel.spi.EndpointStrategy;
import org.apache.camel.spi.EventFactory;
@@ -353,6 +354,10 @@ public final class DefaultConfigurationConfigurer {
if (ssr != null) {
ecc.setStartupStepRecorder(ssr);
}
+ CliConnectorFactory ccf = getSingleBeanOfType(registry,
CliConnectorFactory.class);
+ if (ccf != null) {
+ ecc.setCliConnectorFactory(ccf);
+ }
PropertiesComponent pc = getSingleBeanOfType(registry,
PropertiesComponent.class);
if (pc != null) {
ecc.setPropertiesComponent(pc);
diff --git a/docs/components/modules/others/nav.adoc
b/docs/components/modules/others/nav.adoc
index 3a4e32a00e4..a531911b5e3 100644
--- a/docs/components/modules/others/nav.adoc
+++ b/docs/components/modules/others/nav.adoc
@@ -8,6 +8,7 @@
** xref:cdi.adoc[CDI]
** xref:cdi-jta.adoc[CDI JTA]
** xref:cdi-main.adoc[CDI Main]
+** xref:cli-connector.adoc[CLI Connector]
** xref:cloudevents.adoc[Cloudevents]
** xref:csimple-joor.adoc[CSimple jOOR]
** xref:cxf-transport.adoc[CXF Transport]
diff --git a/docs/components/modules/others/pages/cli-connector.adoc
b/docs/components/modules/others/pages/cli-connector.adoc
new file mode 120000
index 00000000000..fb1b71544cb
--- /dev/null
+++ b/docs/components/modules/others/pages/cli-connector.adoc
@@ -0,0 +1 @@
+../../../../../dsl/camel-cli-connector/src/main/docs/cli-connector.adoc
\ No newline at end of file
diff --git a/dsl/camel-cli-connector/pom.xml b/dsl/camel-cli-connector/pom.xml
new file mode 100644
index 00000000000..e5a568f1be9
--- /dev/null
+++ b/dsl/camel-cli-connector/pom.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>dsl</artifactId>
+ <version>3.19.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>camel-cli-connector</artifactId>
+ <packaging>jar</packaging>
+ <name>Camel :: DSL :: CLI Connector</name>
+ <description>Runtime adapter connecting with Camel CLI</description>
+
+ <properties>
+ <firstVersion>3.19.0</firstVersion>
+ <title>CLI Connector</title>
+ <label>tooling</label>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-support</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-util-json</artifactId>
+ </dependency>
+
+ <!-- insights -->
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-console</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-health</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-management</artifactId>
+ </dependency>
+
+ <!-- test dependencies -->
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-test-junit5</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-slf4j-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-package-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>generate</id>
+ <goals>
+ <goal>generate</goal>
+ </goals>
+ <phase>process-classes</phase>
+ </execution>
+ <execution>
+ <id>generate-postcompile</id>
+ <goals>
+ <goal>generate-postcompile</goal>
+ </goals>
+ <phase>prepare-package</phase>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>initialize</phase>
+ <goals>
+ <goal>add-source</goal>
+ <goal>add-resource</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>src/generated/java</source>
+ </sources>
+ <resources>
+ <resource>
+
<directory>src/generated/resources</directory>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
\ No newline at end of file
diff --git
a/dsl/camel-cli-connector/src/generated/resources/META-INF/services/org/apache/camel/cli-connector-factory
b/dsl/camel-cli-connector/src/generated/resources/META-INF/services/org/apache/camel/cli-connector-factory
new file mode 100644
index 00000000000..c5d7357fc02
--- /dev/null
+++
b/dsl/camel-cli-connector/src/generated/resources/META-INF/services/org/apache/camel/cli-connector-factory
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.cli.connector.DefaultCliConnectorFactory
diff --git
a/dsl/camel-cli-connector/src/generated/resources/META-INF/services/org/apache/camel/other.properties
b/dsl/camel-cli-connector/src/generated/resources/META-INF/services/org/apache/camel/other.properties
new file mode 100644
index 00000000000..89f0cd06c6e
--- /dev/null
+++
b/dsl/camel-cli-connector/src/generated/resources/META-INF/services/org/apache/camel/other.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+name=cli-connector
+groupId=org.apache.camel
+artifactId=camel-cli-connector
+version=3.19.0-SNAPSHOT
+projectName=Camel :: DSL :: CLI Connector
+projectDescription=Runtime adapter connecting with Camel CLI
diff --git a/dsl/camel-cli-connector/src/generated/resources/cli-connector.json
b/dsl/camel-cli-connector/src/generated/resources/cli-connector.json
new file mode 100644
index 00000000000..93654b1747b
--- /dev/null
+++ b/dsl/camel-cli-connector/src/generated/resources/cli-connector.json
@@ -0,0 +1,15 @@
+{
+ "other": {
+ "kind": "other",
+ "name": "cli-connector",
+ "title": "CLI Connector",
+ "description": "Runtime adapter connecting with Camel CLI",
+ "deprecated": false,
+ "firstVersion": "3.19.0",
+ "label": "tooling",
+ "supportLevel": "Preview",
+ "groupId": "org.apache.camel",
+ "artifactId": "camel-cli-connector",
+ "version": "3.19.0-SNAPSHOT"
+ }
+}
diff --git a/dsl/camel-cli-connector/src/main/docs/cli-connector.adoc
b/dsl/camel-cli-connector/src/main/docs/cli-connector.adoc
new file mode 100644
index 00000000000..45876334430
--- /dev/null
+++ b/dsl/camel-cli-connector/src/main/docs/cli-connector.adoc
@@ -0,0 +1,27 @@
+= CLI Connector Component
+:doctitle: CLI Connector
+:shortname: cli-connector
+:artifactid: camel-cli-connector
+:description: Runtime adapter connecting with Camel CLI
+:since: 3.19
+:supportlevel: Preview
+
+*Since Camel {since}*
+
+The camel-cli-connector allows the Camel CLI to be able to manage running
Camel integrations.
+
+Currently, only a local connector is provided, which means that the Camel CLI
can only be
+managing local running Camel integrations.
+
+These integrations can be using different runtimes such as Camel Main, Camel
Spring Boot or Camel Quarkus etc.
+
+
+== Auto-detection from classpath
+
+To use this implementation all you need to do is to add the
`camel-cli-connector` dependency to the classpath,
+and Camel should auto-detect this on startup and log as follows:
+
+[source,text]
+----
+Local CLI Connector started
+----
diff --git
a/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/DefaultCliConnectorFactory.java
b/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/DefaultCliConnectorFactory.java
new file mode 100644
index 00000000000..07f59815f6e
--- /dev/null
+++
b/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/DefaultCliConnectorFactory.java
@@ -0,0 +1,71 @@
+/*
+ * 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.cli.connector;
+
+import org.apache.camel.Service;
+import org.apache.camel.spi.CliConnectorFactory;
+import org.apache.camel.spi.annotations.JdkService;
+
+@JdkService(CliConnectorFactory.FACTORY)
+public class DefaultCliConnectorFactory implements CliConnectorFactory {
+
+ private boolean enabled = true;
+ private String runtime;
+ private String runtimeVersion;
+
+ @Override
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ @Override
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ @Override
+ public String getRuntime() {
+ return runtime;
+ }
+
+ @Override
+ public void setRuntime(String runtime) {
+ this.runtime = runtime;
+ }
+
+ public String getRuntimeVersion() {
+ return runtimeVersion;
+ }
+
+ public void setRuntimeVersion(String runtimeVersion) {
+ this.runtimeVersion = runtimeVersion;
+ }
+
+ @Override
+ public Service createConnector() {
+ if (enabled) {
+ return new LocalCliConnector();
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "camel-cli-connector";
+ }
+}
diff --git
a/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java
b/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java
new file mode 100644
index 00000000000..affeb5dc93a
--- /dev/null
+++
b/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java
@@ -0,0 +1,206 @@
+/*
+ * 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.cli.connector;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.Locale;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.console.DevConsole;
+import org.apache.camel.health.HealthCheck;
+import org.apache.camel.health.HealthCheckHelper;
+import org.apache.camel.spi.CliConnectorFactory;
+import org.apache.camel.support.service.ServiceSupport;
+import org.apache.camel.util.FileUtil;
+import org.apache.camel.util.IOHelper;
+import org.apache.camel.util.concurrent.ThreadHelper;
+import org.apache.camel.util.json.JsonObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * CLI Connector for local management of Camel integrations from the Camel CLI.
+ */
+public class LocalCliConnector extends ServiceSupport implements
CamelContextAware {
+
+ private static final Logger LOG =
LoggerFactory.getLogger(LocalCliConnector.class);
+
+ private CamelContext camelContext;
+ private int delay = 2000;
+ private String platform;
+ private String platformVersion;
+ private ScheduledExecutorService executor;
+ private File lockFile;
+ private File statusFile;
+
+ @Override
+ public CamelContext getCamelContext() {
+ return camelContext;
+ }
+
+ @Override
+ public void setCamelContext(CamelContext camelContext) {
+ this.camelContext = camelContext;
+ }
+
+ @Override
+ protected void doStart() throws Exception {
+ // create thread from JDK so it is not managed by Camel because we
want the pool to be independent when
+ // camel is being stopped which otherwise can lead to stopping the
thread pool while the task is running
+ executor = Executors.newSingleThreadScheduledExecutor(r -> {
+ String threadName = ThreadHelper.resolveThreadName(null,
"LocalCliConnector");
+ return new Thread(r, threadName);
+ });
+
+ lockFile = createLockFile(getPid());
+ if (lockFile != null) {
+ statusFile = createLockFile(lockFile.getName() + "-status.json");
+ }
+ executor.scheduleWithFixedDelay(this::statusTask, 1000, delay,
TimeUnit.MILLISECONDS);
+
+ // what platform are we running
+ CliConnectorFactory ccf =
camelContext.adapt(ExtendedCamelContext.class).getCliConnectorFactory();
+ platform = ccf.getRuntime();
+ if (platform == null) {
+ // use camel context name to guess platform if not specified
+ String sn =
camelContext.getClass().getSimpleName().toLowerCase(Locale.ROOT);
+ if (sn.contains("boot")) {
+ platform = "Spring Boot";
+ } else if (sn.contains("spring")) {
+ platform = "Spring";
+ } else if (sn.contains("quarkus")) {
+ platform = "Quarkus";
+ } else if (sn.contains("osgi")) {
+ platform = "Karaf";
+ } else if (sn.contains("cdi")) {
+ platform = "CDI";
+ } else if (sn.contains("kamelet") ||
camelContext.getName().equals("CamelJBang")) {
+ platform = "JBang";
+ // dev.jbang.BuildConfig
+ // dev.jbang.util.getJBangVersion
+ } else {
+ platform = "Camel";
+ }
+ }
+ platformVersion = ccf.getRuntimeVersion();
+
+ LOG.info("Local CLI Connector started");
+ }
+
+ protected void statusTask() {
+ // if the lock file is deleted then stop
+ if (!lockFile.exists()) {
+ try {
+ camelContext.stop();
+ } finally {
+ if (lockFile != null) {
+ FileUtil.deleteFile(lockFile);
+ }
+ if (statusFile != null) {
+ FileUtil.deleteFile(statusFile);
+ }
+ }
+ return;
+ }
+ try {
+ JsonObject root = new JsonObject();
+
+ // what runtime are in use
+ JsonObject rc = new JsonObject();
+ rc.put("platform", platform);
+ if (platformVersion != null) {
+ rc.put("version", platformVersion);
+ }
+ root.put("runtime", rc);
+
+ // collect details via console
+ DevConsole dc = camelContext.adapt(ExtendedCamelContext.class)
+ .getDevConsoleResolver().resolveDevConsole("context");
+ DevConsole dc2 = camelContext.adapt(ExtendedCamelContext.class)
+ .getDevConsoleResolver().resolveDevConsole("route");
+ int ready = 0;
+ int total = 0;
+ if (dc != null && dc2 != null) {
+ JsonObject json = (JsonObject)
dc.call(DevConsole.MediaType.JSON);
+ JsonObject json2 = (JsonObject)
dc2.call(DevConsole.MediaType.JSON);
+ if (json != null && json2 != null) {
+ root.put("context", json);
+ root.put("routes", json2.get("routes"));
+ }
+ }
+ // and health-check readiness
+ Collection<HealthCheck.Result> res =
HealthCheckHelper.invokeReadiness(camelContext);
+ for (var r : res) {
+ if (r.getState().equals(HealthCheck.State.UP)) {
+ ready++;
+ }
+ total++;
+ }
+ JsonObject hc = new JsonObject();
+ hc.put("ready", ready);
+ hc.put("total", total);
+ root.put("healthChecks", hc);
+
+ LOG.trace("Updating status file: {}", statusFile);
+ IOHelper.writeText(root.toJson(), statusFile);
+ } catch (Throwable e) {
+ // ignore
+ }
+ }
+
+ @Override
+ protected void doStop() throws Exception {
+ // cleanup
+ if (executor != null) {
+ camelContext.getExecutorServiceManager().shutdown(executor);
+ executor = null;
+ }
+ }
+
+ private static String getPid() {
+ try {
+ return "" + ProcessHandle.current().pid();
+ } catch (Throwable e) {
+ return null;
+ }
+ }
+
+ private static File createLockFile(String name) {
+ File answer = null;
+ if (name != null) {
+ File dir = new File(System.getProperty("user.home"), ".camel");
+ try {
+ dir.mkdirs();
+ answer = new File(dir, name);
+ if (!answer.exists()) {
+ answer.createNewFile();
+ }
+ answer.deleteOnExit();
+ } catch (Exception e) {
+ answer = null;
+ }
+ }
+ return answer;
+ }
+
+}
diff --git a/dsl/camel-jbang/camel-jbang-core/pom.xml
b/dsl/camel-jbang/camel-jbang-core/pom.xml
index d08abf5d450..823ffa790e0 100644
--- a/dsl/camel-jbang/camel-jbang-core/pom.xml
+++ b/dsl/camel-jbang/camel-jbang-core/pom.xml
@@ -59,6 +59,10 @@
</dependency>
<!-- cli -->
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-cli-connector</artifactId>
+ </dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
index 35dbc130deb..ce959f140db 100644
---
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
+++
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
@@ -30,16 +30,12 @@ import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.Set;
import java.util.StringJoiner;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -49,12 +45,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import io.apicurio.datamodels.Library;
import io.apicurio.datamodels.openapi.models.OasDocument;
import org.apache.camel.CamelContext;
-import org.apache.camel.ExtendedCamelContext;
-import org.apache.camel.console.DevConsole;
import org.apache.camel.dsl.jbang.core.common.RuntimeUtil;
import org.apache.camel.generator.openapi.RestDslGenerator;
-import org.apache.camel.health.HealthCheck;
-import org.apache.camel.health.HealthCheckHelper;
import org.apache.camel.impl.lw.LightweightCamelContext;
import org.apache.camel.main.KameletMain;
import org.apache.camel.main.download.DownloadListener;
@@ -64,7 +56,6 @@ import org.apache.camel.util.FileUtil;
import org.apache.camel.util.IOHelper;
import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.StringHelper;
-import org.apache.camel.util.json.JsonObject;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.config.Configurator;
import picocli.CommandLine;
@@ -95,9 +86,6 @@ class Run extends CamelCommand {
"^\\s*public class\\s+([a-zA-Z0-9]*)[\\s+|;].*$",
Pattern.MULTILINE);
private CamelContext context;
- private File lockFile;
- private File statusFile;
- private ScheduledExecutorService executor;
private boolean silentRun;
private boolean pipeRun;
@@ -165,10 +153,6 @@ class Run extends CamelCommand {
@Option(names = { "-p", "--prop", "--property" }, description =
"Additional properties (override existing)", arity = "0")
String[] property;
- @Option(names = { "--file-lock" },
- description = "Whether to create a temporary file lock, which upon
deleting triggers this process to terminate", defaultValue = "true")
- boolean fileLock = true;
-
@Option(names = { "--jfr" },
description = "Enables Java Flight Recorder saving recording to
disk on exit")
boolean jfr;
@@ -245,12 +229,6 @@ class Run extends CamelCommand {
}
private int stop() {
- if (lockFile != null) {
- FileUtil.deleteFile(lockFile);
- }
- if (statusFile != null) {
- FileUtil.deleteFile(statusFile);
- }
return 0;
}
@@ -409,10 +387,6 @@ class Run extends CamelCommand {
writeSetting(main, profileProperties, "camel.jbang.jfr", jfr ||
jfrProfile != null ? "jfr" : null);
writeSetting(main, profileProperties, "camel.jbang.jfr-profile",
jfrProfile != null ? jfrProfile : null);
- if (fileLock) {
- initLockFile(main);
- }
-
StringJoiner js = new StringJoiner(",");
StringJoiner sjReload = new StringJoiner(",");
StringJoiner sjClasspathFiles = new StringJoiner(",");
@@ -571,57 +545,6 @@ class Run extends CamelCommand {
return main.getExitCode();
}
- private void initLockFile(KameletMain main) {
- lockFile = createLockFile(getPid());
- if (lockFile != null) {
- statusFile = createLockFile(lockFile.getName() + "-status.json");
- }
- // to trigger shutdown on file lock deletion
- executor = Executors.newSingleThreadScheduledExecutor();
- executor.scheduleWithFixedDelay(() -> {
- // if the lock file is deleted then stop
- if (!lockFile.exists()) {
- context.stop();
- return;
- }
- try {
- // update status file with details from the context console
- JsonObject root = new JsonObject();
- DevConsole dc =
main.getCamelContext().adapt(ExtendedCamelContext.class)
- .getDevConsoleResolver().resolveDevConsole("context");
- DevConsole dc2 =
main.getCamelContext().adapt(ExtendedCamelContext.class)
- .getDevConsoleResolver().resolveDevConsole("route");
- int ready = 0;
- int total = 0;
- if (dc != null && dc2 != null) {
- JsonObject json = (JsonObject)
dc.call(DevConsole.MediaType.JSON);
- JsonObject json2 = (JsonObject)
dc2.call(DevConsole.MediaType.JSON);
- if (json != null && json2 != null) {
- root.put("context", json);
- json.put("runtime", "camel-jbang");
- root.put("routes", json2.get("routes"));
- }
- }
- // and health-check readiness
- Collection<HealthCheck.Result> res =
HealthCheckHelper.invokeReadiness(main.getCamelContext());
- for (var r : res) {
- if (r.getState().equals(HealthCheck.State.UP)) {
- ready++;
- }
- total++;
- }
- JsonObject hc = new JsonObject();
- hc.put("ready", ready);
- hc.put("total", total);
- root.put("healthChecks", hc);
-
- IOHelper.writeText(root.toJson(), statusFile);
- } catch (Throwable e) {
- // ignore
- }
- }, 2000, 2000, TimeUnit.MILLISECONDS);
- }
-
private String evalGistSource(KameletMain main, String file) throws
Exception {
StringJoiner routes = new StringJoiner(",");
StringJoiner kamelets = new StringJoiner(",");
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextStatus.java
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextStatus.java
index 7ed706897ef..73fba159cf0 100644
---
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextStatus.java
+++
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextStatus.java
@@ -81,10 +81,12 @@ public class CamelContextStatus extends ProcessBaseCommand {
row.ago = TimeUtils.printSince(extractSince(ph));
JsonObject root = loadStatus(ph.pid());
if (root != null) {
- JsonObject hc = (JsonObject)
root.get("healthChecks");
- row.ready = hc != null ? hc.getString("ready") +
"/" + hc.getString("total") : null;
+ JsonObject runtime = (JsonObject)
root.get("runtime");
+ row.platform = runtime != null ?
runtime.getString("platform") : null;
+ row.platformVersion = runtime != null ?
runtime.getString("platformVersion") : null;
JsonObject context = (JsonObject)
root.get("context");
row.state =
context.getString("state").toLowerCase(Locale.ROOT);
+ row.camelVersion = context.getString("version");
Map<String, ?> stats =
context.getMap("statistics");
if (stats != null) {
row.total =
stats.get("exchangesTotal").toString();
@@ -95,6 +97,8 @@ public class CamelContextStatus extends ProcessBaseCommand {
row.sinceLast = last.toString();
}
}
+ JsonObject hc = (JsonObject)
root.get("healthChecks");
+ row.ready = hc != null ? hc.getString("ready") +
"/" + hc.getString("total") : null;
}
rows.add(row);
}
@@ -105,6 +109,8 @@ public class CamelContextStatus extends ProcessBaseCommand {
new
Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid),
new
Column().header("NAME").dataAlign(HorizontalAlign.LEFT).maxWidth(30,
OverflowBehaviour.ELLIPSIS)
.with(r -> r.name),
+ new
Column().header("CAMEL").dataAlign(HorizontalAlign.LEFT).with(r ->
r.camelVersion),
+ new
Column().header("PLATFORM").dataAlign(HorizontalAlign.LEFT).with(this::getPlatform),
new
Column().header("READY").dataAlign(HorizontalAlign.CENTER).with(r -> r.ready),
new
Column().header("STATE").headerAlign(HorizontalAlign.CENTER)
.with(r -> StringHelper.capitalize(r.state)),
@@ -118,6 +124,14 @@ public class CamelContextStatus extends ProcessBaseCommand
{
return 0;
}
+ private String getPlatform(Row r) {
+ if (r.platformVersion != null) {
+ return r.platform + " v" + r.platformVersion + ")";
+ } else {
+ return r.platform;
+ }
+ }
+
private JsonObject loadStatus(long pid) {
try {
File f = getStatusFile("" + pid);
@@ -135,6 +149,9 @@ public class CamelContextStatus extends ProcessBaseCommand {
private static class Row {
String pid;
+ String platform;
+ String platformVersion;
+ String camelVersion;
String name;
String ready;
String state;
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProcess.java
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProcess.java
index 55233f1f528..cb1046c55c8 100644
---
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProcess.java
+++
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProcess.java
@@ -45,7 +45,9 @@ public class ListProcess extends ProcessBaseCommand {
public Integer call() throws Exception {
List<Row> rows = new ArrayList<>();
+ final long cur = ProcessHandle.current().pid();
ProcessHandle.allProcesses()
+ .filter(ph -> ph.pid() != cur)
.sorted((o1, o2) -> {
switch (sort) {
case "pid":
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ProcessBaseCommand.java
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ProcessBaseCommand.java
index 82abe67c958..8181e14150a 100644
---
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ProcessBaseCommand.java
+++
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ProcessBaseCommand.java
@@ -51,8 +51,10 @@ abstract class ProcessBaseCommand extends CamelCommand {
}
}
+ final long cur = ProcessHandle.current().pid();
final String pattern = name;
ProcessHandle.allProcesses()
+ .filter(ph -> ph.pid() != cur)
.forEach(ph -> {
String pName = extractName(ph);
// ignore file extension, so it is easier to match by name
@@ -67,6 +69,45 @@ abstract class ProcessBaseCommand extends CamelCommand {
static String extractName(ProcessHandle ph) {
String cl = ph.info().commandLine().orElse("");
+
+ String name = extractCamelJBangName(cl);
+ if (name == null) {
+ name = extractCamelMavenName(cl);
+ }
+ if (name == null) {
+ name = extractCamelMain(cl);
+ }
+
+ return name == null ? "" : name;
+ }
+
+ private static String extractCamelMavenName(String cl) {
+ String name = StringHelper.before(cl, " camel:run");
+ if (name != null) {
+ if
(name.contains("org.codehaus.plexus.classworlds.launcher.Launcher")) {
+ return "mvn camel:run";
+ }
+ }
+
+ return null;
+ }
+
+ private static String extractCamelMain(String cl) {
+ if (cl != null) {
+ if (cl.contains("camel-main")) {
+ int pos = cl.lastIndexOf(" ");
+ String after = cl.substring(pos);
+ after = after.trim();
+ if (after.matches("[\\w|.]+")) {
+ return "camel-main";
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private static String extractCamelJBangName(String cl) {
String name = StringHelper.after(cl, "main.CamelJBang run");
if (name != null) {
name = name.trim();
@@ -83,7 +124,7 @@ abstract class ProcessBaseCommand extends CamelCommand {
return js.toString();
}
- return "";
+ return null;
}
static long extractSince(ProcessHandle ph) {
diff --git a/dsl/pom.xml b/dsl/pom.xml
index 5a4ec865a65..e3a29e2680f 100644
--- a/dsl/pom.xml
+++ b/dsl/pom.xml
@@ -42,6 +42,7 @@
<modules>
<module>camel-endpointdsl</module>
<module>camel-componentdsl</module>
+ <module>camel-cli-connector</module>
<module>camel-dsl-support</module>
<module>camel-dsl-modeline</module>
<module>camel-endpointdsl-support</module>
diff --git a/parent/pom.xml b/parent/pom.xml
index 6ff0661c1e6..c1fd3805c3b 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -1100,6 +1100,11 @@
<artifactId>camel-chunk</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-cli-connector</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-cloudevents</artifactId>