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/06/22 04:38:45 UTC

[camel] branch main updated: CAMEL-18214: Allow Backlog Debugger and test debugger to work at the same time (#7846)

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 984c3d3052a CAMEL-18214: Allow Backlog Debugger and test debugger to work at the same time (#7846)
984c3d3052a is described below

commit 984c3d3052a3e3e2ec13e816e519024f55623a37
Author: Nicolas Filotto <es...@users.noreply.github.com>
AuthorDate: Wed Jun 22 06:38:39 2022 +0200

    CAMEL-18214: Allow Backlog Debugger and test debugger to work at the same time (#7846)
---
 .../src/main/docs/test-main-junit5.adoc            | 36 ++++++++++++++++
 .../camel/test/main/junit5/CamelMainExtension.java | 16 ++++++-
 .../camel/test/main/junit5/CamelMainTest.java      |  7 +++
 .../main/junit5/annotation/WithUseJMXTest.java     | 46 ++++++++++++++++++++
 .../test/main/junit5/legacy/WithUseJMXTest.java    | 50 ++++++++++++++++++++++
 .../apache/camel/impl/engine/DefaultChannel.java   | 21 ++++++---
 6 files changed, 167 insertions(+), 9 deletions(-)

diff --git a/components/camel-test/camel-test-main-junit5/src/main/docs/test-main-junit5.adoc b/components/camel-test/camel-test-main-junit5/src/main/docs/test-main-junit5.adoc
index d929fa95852..078a4a17160 100644
--- a/components/camel-test/camel-test-main-junit5/src/main/docs/test-main-junit5.adoc
+++ b/components/camel-test/camel-test-main-junit5/src/main/docs/test-main-junit5.adoc
@@ -519,6 +519,42 @@ The method `isUseDebugger()` can be overridden to return `true` indicating that
 === Annotation ===
 The test class needs to implement the interface `org.apache.camel.test.main.junit5.DebuggerCallback` to enable the feature. The methods `debugBefore` and `debugAfter` can then be implemented to execute some specific code for debugging purpose.
 
+== Enable JMX
+
+JMX is disabled by default when launching the tests, however if needed, it is still possible to enable it.
+
+=== Legacy ===
+The method `useJmx()` can be overridden to return `true`. It returns `false` by default.
+
+=== Annotation ===
+The attribute `useJmx` can be set to `true`. It is set to `false` by default.
+
+In the next examples, JMX has been enabled for the test.
+
+=== Legacy ===
+[source,java]
+----
+class SomeTest extends CamelMainTestSupport {
+
+    @Override
+    protected boolean useJmx() {
+        return true;
+    }
+
+    // Rest of the test class
+}
+----
+
+=== Annotation ===
+[source,java]
+----
+@CamelMainTest(useJmx = true)
+class SomeTest {
+
+    // Rest of the test class
+}
+----
+
 == Nested tests
 
 The annotation based approach supports natively https://junit.org/junit5/docs/current/user-guide/#writing-tests-nested[Nested tests]. It is even possible to annotate `@Nested` test class with `@CamelMainTest` to change the configuration inherited from the outer class however please note that not all attributes can be set at nested test class level. Indeed, for the sake of simplicity, the attributes `dumpRouteCoverage` and `shutdownTimeout` can only be set at outer class level.
diff --git a/components/camel-test/camel-test-main-junit5/src/main/java/org/apache/camel/test/main/junit5/CamelMainExtension.java b/components/camel-test/camel-test-main-junit5/src/main/java/org/apache/camel/test/main/junit5/CamelMainExtension.java
index 524aa5354fd..d5838ee81d5 100644
--- a/components/camel-test/camel-test-main-junit5/src/main/java/org/apache/camel/test/main/junit5/CamelMainExtension.java
+++ b/components/camel-test/camel-test-main-junit5/src/main/java/org/apache/camel/test/main/junit5/CamelMainExtension.java
@@ -109,7 +109,7 @@ final class CamelMainExtension
     private CamelMainContext createCamelMainContextAndStart(ExtensionContext context) {
         try {
             final CamelMainContext camelMainContext = CamelMainContext.builder(context)
-                    .useJmx(isRouteCoverageEnabled(context))
+                    .useJmx(useJmx(context) || isRouteCoverageEnabled(context))
                     .build();
             camelMainContext.start();
             return camelMainContext;
@@ -148,7 +148,7 @@ final class CamelMainExtension
             ManagedCamelContextMBean managedCamelContext = mc == null ? null : mc.getManagedCamelContext();
             if (managedCamelContext == null) {
                 LOG.warn("Cannot dump route coverage to file as JMX is not enabled. "
-                         + "Add camel-management JAR as dependency and/or override useJmx() method to enable JMX in the unit test classes.");
+                         + "Add camel-management JAR as dependency to enable JMX in the unit test classes.");
             } else {
                 routeCoverageDumper.dump(managedCamelContext, camelContext, dir, name, requiredTestClass.getName(),
                         currentTestName,
@@ -170,4 +170,16 @@ final class CamelMainExtension
                 || context.getRequiredTestInstances().getAllInstances().get(0).getClass()
                         .getAnnotation(CamelMainTest.class).dumpRouteCoverage();
     }
+
+    /**
+     * Indicates whether JMX should be used during testing according to the given extension context.
+     * <p/>
+     * In case of {@code @Nested} test classes, the value is always extracted from the annotation of the outer class.
+     *
+     * @return {@code true} if JMX should be used, {@code false} otherwise.
+     */
+    private boolean useJmx(ExtensionContext context) {
+        return context.getRequiredTestInstances().getAllInstances().get(0).getClass()
+                .getAnnotation(CamelMainTest.class).useJmx();
+    }
 }
diff --git a/components/camel-test/camel-test-main-junit5/src/main/java/org/apache/camel/test/main/junit5/CamelMainTest.java b/components/camel-test/camel-test-main-junit5/src/main/java/org/apache/camel/test/main/junit5/CamelMainTest.java
index 59554c27b70..7ad2d24d7b0 100644
--- a/components/camel-test/camel-test-main-junit5/src/main/java/org/apache/camel/test/main/junit5/CamelMainTest.java
+++ b/components/camel-test/camel-test-main-junit5/src/main/java/org/apache/camel/test/main/junit5/CamelMainTest.java
@@ -218,6 +218,13 @@ public @interface CamelMainTest {
      */
     boolean dumpRouteCoverage() default false;
 
+    /**
+     * Whether JMX should be used during testing.
+     *
+     * @return <tt>false</tt> by default.
+     */
+    boolean useJmx() default false;
+
     /**
      * Returns the timeout to use when shutting down (unit in seconds).
      * <p/>
diff --git a/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/annotation/WithUseJMXTest.java b/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/annotation/WithUseJMXTest.java
new file mode 100644
index 00000000000..2133b79fadf
--- /dev/null
+++ b/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/annotation/WithUseJMXTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.test.main.junit5.annotation;
+
+import org.apache.camel.BeanInject;
+import org.apache.camel.CamelContext;
+import org.apache.camel.api.management.ManagedCamelContext;
+import org.apache.camel.api.management.mbean.ManagedCamelContextMBean;
+import org.apache.camel.test.main.junit5.CamelMainTest;
+import org.apache.camel.test.main.junit5.common.MyMainClass;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+/**
+ * A test class ensuring that JMX can be enabled.
+ */
+@CamelMainTest(mainClass = MyMainClass.class, useJmx = true)
+class WithUseJMXTest {
+
+    @BeanInject
+    CamelContext context;
+
+    @Test
+    void shouldFindTheManagedCamelContext() {
+        assertNotNull(context);
+        ManagedCamelContext mc = context.getExtension(ManagedCamelContext.class);
+        assertNotNull(mc);
+        ManagedCamelContextMBean managedCamelContext = mc.getManagedCamelContext();
+        assertNotNull(managedCamelContext);
+    }
+}
diff --git a/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/legacy/WithUseJMXTest.java b/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/legacy/WithUseJMXTest.java
new file mode 100644
index 00000000000..bb9fbb57622
--- /dev/null
+++ b/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/legacy/WithUseJMXTest.java
@@ -0,0 +1,50 @@
+/*
+ * 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.test.main.junit5.legacy;
+
+import org.apache.camel.api.management.ManagedCamelContext;
+import org.apache.camel.api.management.mbean.ManagedCamelContextMBean;
+import org.apache.camel.test.main.junit5.CamelMainTestSupport;
+import org.apache.camel.test.main.junit5.common.MyMainClass;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+/**
+ * A test class ensuring that JMX can be enabled.
+ */
+class WithUseJMXTest extends CamelMainTestSupport {
+
+    @Override
+    protected Class<?> getMainClass() {
+        return MyMainClass.class;
+    }
+
+    @Override
+    protected boolean useJmx() {
+        return true;
+    }
+
+    @Test
+    void shouldFindTheManagedCamelContext() {
+        assertNotNull(context);
+        ManagedCamelContext mc = context.getExtension(ManagedCamelContext.class);
+        assertNotNull(mc);
+        ManagedCamelContextMBean managedCamelContext = mc.getManagedCamelContext();
+        assertNotNull(managedCamelContext);
+    }
+}
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultChannel.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultChannel.java
index 32382c824ea..6b5503177e7 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultChannel.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultChannel.java
@@ -180,13 +180,14 @@ public class DefaultChannel extends CamelInternalProcessor implements Channel {
         // then wrap the output with the tracer and debugger (debugger first,
         // as we do not want regular tracer to trace the debugger)
         if (route.isDebugging()) {
-            if (camelContext.getDebugger() != null) {
+            final Debugger customDebugger = camelContext.getDebugger();
+            if (customDebugger != null) {
                 // use custom debugger
-                Debugger debugger = camelContext.getDebugger();
-                addAdvice(new DebuggerAdvice(debugger, nextProcessor, targetOutputDef));
-            } else {
+                addAdvice(new DebuggerAdvice(customDebugger, nextProcessor, targetOutputDef));
+            }
+            BacklogDebugger debugger = getBacklogDebugger(camelContext, customDebugger == null);
+            if (debugger != null) {
                 // use backlog debugger
-                BacklogDebugger debugger = getOrCreateBacklogDebugger(camelContext);
                 camelContext.addService(debugger);
                 addAdvice(new BacklogDebuggerAdvice(debugger, nextProcessor, targetOutputDef));
             }
@@ -284,7 +285,13 @@ public class DefaultChannel extends CamelInternalProcessor implements Channel {
         return tracer;
     }
 
-    private static BacklogDebugger getOrCreateBacklogDebugger(CamelContext camelContext) {
+    /**
+     * @param  camelContext   the camel context from which the {@link BacklogDebugger} should be found.
+     * @param  createIfAbsent indicates whether a {@link BacklogDebugger} should be created if it cannot be found
+     * @return                the instance of {@link BacklogDebugger} that could be found in the context or that was
+     *                        created if {@code createIfAbsent} is set to {@code true}, {@code null} otherwise.
+     */
+    private static BacklogDebugger getBacklogDebugger(CamelContext camelContext, boolean createIfAbsent) {
         BacklogDebugger debugger = null;
         if (camelContext.getRegistry() != null) {
             // lookup in registry
@@ -296,7 +303,7 @@ public class DefaultChannel extends CamelInternalProcessor implements Channel {
         if (debugger == null) {
             debugger = camelContext.hasService(BacklogDebugger.class);
         }
-        if (debugger == null) {
+        if (debugger == null && createIfAbsent) {
             // fallback to use the default debugger
             debugger = BacklogDebugger.createDebugger(camelContext);
         }