You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2022/02/16 10:28:02 UTC

[camel] branch main updated (de53026 -> 5209fc6)

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

davsclaus pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git.


    from de53026  (chores) ci: use suggestion from SonarCloud to improve analysis time
     new 3c53bf3  CAMEL-17654: camel-debug - Make it possible to do remote JMX RMI debugging
     new 5209fc6  CAMEL-17645: rename modeLine to modeline

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 components/camel-debug/src/main/docs/debug.adoc    |  13 ++
 .../camel/impl/debugger/CamelDebuggerFactory.java  |   3 +
 .../camel/impl/debugger/JmxConnectorService.java   | 148 +++++++++++++++++++++
 .../MainConfigurationPropertiesConfigurer.java     |   6 +
 .../camel-main-configuration-metadata.json         |   1 +
 core/camel-main/src/main/docs/main.adoc            |   3 +-
 .../camel/main/DefaultConfigurationConfigurer.java |   2 +-
 .../camel/main/DefaultConfigurationProperties.java |   4 +-
 8 files changed, 176 insertions(+), 4 deletions(-)
 create mode 100644 components/camel-debug/src/main/java/org/apache/camel/impl/debugger/JmxConnectorService.java

[camel] 02/02: CAMEL-17645: rename modeLine to modeline

Posted by da...@apache.org.
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

commit 5209fc65284c1faa91b8373ee8feeae2bd6f04f8
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Feb 16 11:21:51 2022 +0100

    CAMEL-17645: rename modeLine to modeline
---
 .../apache/camel/main/MainConfigurationPropertiesConfigurer.java    | 6 ++++++
 .../resources/META-INF/camel-main-configuration-metadata.json       | 1 +
 core/camel-main/src/main/docs/main.adoc                             | 3 ++-
 .../java/org/apache/camel/main/DefaultConfigurationConfigurer.java  | 2 +-
 .../java/org/apache/camel/main/DefaultConfigurationProperties.java  | 4 ++--
 5 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
index 000c931..e1fb5a1 100644
--- a/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
+++ b/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
@@ -119,6 +119,8 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp
         case "MdcLoggingKeysPattern": target.setMdcLoggingKeysPattern(property(camelContext, java.lang.String.class, value)); return true;
         case "messagehistory":
         case "MessageHistory": target.setMessageHistory(property(camelContext, boolean.class, value)); return true;
+        case "modeline":
+        case "Modeline": target.setModeline(property(camelContext, boolean.class, value)); return true;
         case "name":
         case "Name": target.setName(property(camelContext, java.lang.String.class, value)); return true;
         case "producertemplatecachesize":
@@ -342,6 +344,8 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp
         case "MdcLoggingKeysPattern": return java.lang.String.class;
         case "messagehistory":
         case "MessageHistory": return boolean.class;
+        case "modeline":
+        case "Modeline": return boolean.class;
         case "name":
         case "Name": return java.lang.String.class;
         case "producertemplatecachesize":
@@ -566,6 +570,8 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp
         case "MdcLoggingKeysPattern": return target.getMdcLoggingKeysPattern();
         case "messagehistory":
         case "MessageHistory": return target.isMessageHistory();
+        case "modeline":
+        case "Modeline": return target.isModeline();
         case "name":
         case "Name": return target.getName();
         case "producertemplatecachesize":
diff --git a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
index e5dc1a5..a3fef16 100644
--- a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
+++ b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
@@ -59,6 +59,7 @@
     { "name": "camel.main.logMask", "description": "Sets whether log mask is enabled or not. Default is false.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.main.mdcLoggingKeysPattern", "description": "Sets the pattern used for determine which custom MDC keys to propagate during message routing when the routing engine continues routing asynchronously for the given message. Setting this pattern to will propagate all custom keys. Or setting the pattern to foo,bar will propagate any keys starting with either foo or bar. Notice that a set of standard Camel MDC keys are always propagated which starts with camel. as key name.  [...]
     { "name": "camel.main.messageHistory", "description": "Sets whether message history is enabled or not. Default is false.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
+    { "name": "camel.main.modeline", "description": "Whether camel-k style modeline is also enabled when not using camel-k. Enabling this allows to use a camel-k like experience by being able to configure various settings using modeline directly in your route source code.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.main.name", "description": "Sets the name of the CamelContext.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String" },
     { "name": "camel.main.producerTemplateCacheSize", "description": "Producer template endpoints cache size.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "integer", "javaType": "int", "defaultValue": 1000 },
     { "name": "camel.main.routeControllerBackOffDelay", "description": "Backoff delay in millis when restarting a route that failed to startup.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "integer", "javaType": "long" },
diff --git a/core/camel-main/src/main/docs/main.adoc b/core/camel-main/src/main/docs/main.adoc
index 4362f86..a29a394 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -18,7 +18,7 @@ The following tables lists all the options:
 
 // main options: START
 === Camel Main configurations
-The camel.main supports 108 options, which are listed below.
+The camel.main supports 109 options, which are listed below.
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
@@ -72,6 +72,7 @@ The camel.main supports 108 options, which are listed below.
 | *camel.main.logMask* | Sets whether log mask is enabled or not. Default is false. | false | boolean
 | *camel.main.mdcLoggingKeys{zwsp}Pattern* | Sets the pattern used for determine which custom MDC keys to propagate during message routing when the routing engine continues routing asynchronously for the given message. Setting this pattern to will propagate all custom keys. Or setting the pattern to foo,bar will propagate any keys starting with either foo or bar. Notice that a set of standard Camel MDC keys are always propagated which starts with camel. as key name. The match rules are a [...]
 | *camel.main.messageHistory* | Sets whether message history is enabled or not. Default is false. | false | boolean
+| *camel.main.modeline* | Whether camel-k style modeline is also enabled when not using camel-k. Enabling this allows to use a camel-k like experience by being able to configure various settings using modeline directly in your route source code. | false | boolean
 | *camel.main.name* | Sets the name of the CamelContext. |  | String
 | *camel.main.producerTemplate{zwsp}CacheSize* | Producer template endpoints cache size. | 1000 | int
 | *camel.main.routeControllerBack{zwsp}OffDelay* | Backoff delay in millis when restarting a route that failed to startup. |  | long
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 ccea368..335e8ed 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
@@ -229,7 +229,7 @@ public final class DefaultConfigurationConfigurer {
         camelContext.setLoadTypeConverters(config.isLoadTypeConverters());
         camelContext.setLoadHealthChecks(config.isLoadHealthChecks());
         camelContext.setDevConsole(config.isDevConsoleEnabled());
-        camelContext.setmodeline(config.ismodeline());
+        camelContext.setmodeline(config.isModeline());
         if (config.isRoutesReloadEnabled()) {
             RouteWatcherReloadStrategy reloader = new RouteWatcherReloadStrategy(
                     config.getRoutesReloadDirectory(), config.isRoutesReloadDirectoryRecursive());
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
index 1ab0977..2b844fe 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
@@ -394,7 +394,7 @@ public abstract class DefaultConfigurationProperties<T> {
         this.devConsoleEnabled = devConsoleEnabled;
     }
 
-    public boolean ismodeline() {
+    public boolean isModeline() {
         return modeline;
     }
 
@@ -402,7 +402,7 @@ public abstract class DefaultConfigurationProperties<T> {
      * Whether camel-k style modeline is also enabled when not using camel-k. Enabling this allows to use a camel-k like
      * experience by being able to configure various settings using modeline directly in your route source code.
      */
-    public void setmodeline(boolean modeline) {
+    public void setModeline(boolean modeline) {
         this.modeline = modeline;
     }
 

[camel] 01/02: CAMEL-17654: camel-debug - Make it possible to do remote JMX RMI debugging

Posted by da...@apache.org.
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

commit 3c53bf3b66de5f159991ddcc91fdfa6437120b4c
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Feb 16 11:19:04 2022 +0100

    CAMEL-17654: camel-debug - Make it possible to do remote JMX RMI debugging
---
 components/camel-debug/src/main/docs/debug.adoc    |  13 ++
 .../camel/impl/debugger/CamelDebuggerFactory.java  |   3 +
 .../camel/impl/debugger/JmxConnectorService.java   | 148 +++++++++++++++++++++
 3 files changed, 164 insertions(+)

diff --git a/components/camel-debug/src/main/docs/debug.adoc b/components/camel-debug/src/main/docs/debug.adoc
index 54f16c7..9ff9e63 100644
--- a/components/camel-debug/src/main/docs/debug.adoc
+++ b/components/camel-debug/src/main/docs/debug.adoc
@@ -22,3 +22,16 @@ and Camel should auto-detect this on startup and log as follows:
 ----
 Detected: camel-debug JAR (enabling Camel Debugging)
 ----
+
+== JMX remote connection
+
+To make it possible for 3rd party tooling to connect to the running Camel application,
+and to perform debugging actions, then Camel will expose a JMX RMI connector port,
+that the tools can use to connect via that allows JMX remote management.
+
+The service URL to connect is:
+
+[source,text]
+----
+service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi/camel
+----
diff --git a/components/camel-debug/src/main/java/org/apache/camel/impl/debugger/CamelDebuggerFactory.java b/components/camel-debug/src/main/java/org/apache/camel/impl/debugger/CamelDebuggerFactory.java
index b2ea55d..87aeaf8 100644
--- a/components/camel-debug/src/main/java/org/apache/camel/impl/debugger/CamelDebuggerFactory.java
+++ b/components/camel-debug/src/main/java/org/apache/camel/impl/debugger/CamelDebuggerFactory.java
@@ -43,6 +43,9 @@ public class CamelDebuggerFactory implements DebuggerFactory {
         });
         camelContext.addService(backlog);
 
+        // to make debugging possible for tooling we need to make it possible to do remote JMX connection
+        camelContext.addService(new JmxConnectorService());
+
         // return null as we fool camel-core into using this backlog debugger as we added it as a service
         return null;
     }
diff --git a/components/camel-debug/src/main/java/org/apache/camel/impl/debugger/JmxConnectorService.java b/components/camel-debug/src/main/java/org/apache/camel/impl/debugger/JmxConnectorService.java
new file mode 100644
index 0000000..5695ab7
--- /dev/null
+++ b/components/camel-debug/src/main/java/org/apache/camel/impl/debugger/JmxConnectorService.java
@@ -0,0 +1,148 @@
+/*
+ * 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.debugger;
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.rmi.NoSuchObjectException;
+import java.rmi.RemoteException;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
+import java.rmi.server.UnicastRemoteObject;
+
+import javax.management.MBeanServer;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.support.service.ServiceSupport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * To make it possible to do JMX debugging via JMX remote
+ */
+public class JmxConnectorService extends ServiceSupport implements CamelContextAware {
+
+    public static final String DEFAULT_HOST = "localhost";
+    public static final int DEFAULT_REGISTRY_PORT = 1099;
+    public static final int DEFAULT_CONNECTION_PORT = -1;
+    public static final String DEFAULT_SERVICE_URL_PATH = "/jmxrmi/camel";
+
+    private static final Logger LOG = LoggerFactory.getLogger(JmxConnectorService.class);
+
+    private CamelContext camelContext;
+    private MBeanServer server;
+    private JMXConnectorServer cs;
+    private Registry registry;
+
+    private boolean createConnector = true;
+
+    @Override
+    public CamelContext getCamelContext() {
+        return camelContext;
+    }
+
+    @Override
+    public void setCamelContext(CamelContext camelContext) {
+        this.camelContext = camelContext;
+    }
+
+    public boolean isCreateConnector() {
+        return createConnector;
+    }
+
+    public void setCreateConnector(boolean createConnector) {
+        this.createConnector = createConnector;
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        server = ManagementFactory.getPlatformMBeanServer();
+
+        if (createConnector) {
+            createJmxConnector(DEFAULT_HOST);
+        }
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        // close JMX Connector, if it was created
+        if (cs != null) {
+            try {
+                cs.stop();
+                LOG.debug("Stopped JMX Connector");
+            } catch (IOException e) {
+                LOG.debug("Error occurred during stopping JMXConnectorService: "
+                          + cs + ". This exception will be ignored.");
+            }
+            cs = null;
+        }
+
+        // Unexport JMX RMI registry, if it was created
+        if (registry != null) {
+            try {
+                UnicastRemoteObject.unexportObject(registry, true);
+                LOG.debug("Unexported JMX RMI Registry");
+            } catch (NoSuchObjectException e) {
+                LOG.debug("Error occurred while unexporting JMX RMI registry. This exception will be ignored.");
+            }
+        }
+    }
+
+    protected void createJmxConnector(String host) throws IOException {
+        int registryPort = DEFAULT_REGISTRY_PORT;
+        String serviceUrlPath = DEFAULT_SERVICE_URL_PATH;
+        int connectorPort = DEFAULT_CONNECTION_PORT;
+
+        try {
+            registry = LocateRegistry.createRegistry(registryPort);
+            LOG.debug("Created JMXConnector RMI registry on port {}", registryPort);
+        } catch (RemoteException ex) {
+            // The registry may had been created, we could get the registry instead
+        }
+
+        // must start with leading slash
+        String path = serviceUrlPath.startsWith("/") ? serviceUrlPath : "/" + serviceUrlPath;
+        // Create an RMI connector and start it
+        final JMXServiceURL url;
+        if (connectorPort > 0) {
+            url = new JMXServiceURL(
+                    "service:jmx:rmi://" + host + ":" + connectorPort + "/jndi/rmi://" + host
+                                    + ":" + registryPort + path);
+        } else {
+            url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + host + ":" + registryPort + path);
+        }
+
+        cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, server);
+
+        // use async thread for starting the JMX Connector
+        // (no need to use a thread pool or enlist in JMX as this thread is terminated when the JMX connector has been started)
+        Thread thread = getCamelContext().getExecutorServiceManager().newThread("CamelJMXConnector", () -> {
+            try {
+                LOG.debug("Staring JMX Connector thread to listen at: {}", url);
+                cs.start();
+                LOG.info("JMX Connector thread started and listening at: {}", url);
+            } catch (IOException ioe) {
+                LOG.warn("Could not start JMXConnector thread at: " + url + ". JMX Connector not in use.", ioe);
+            }
+        });
+        thread.start();
+    }
+}