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

orpiske 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 acd90730d4b CAMEL-19897: another shot at removing isStatisticsEnabled
acd90730d4b is described below

commit acd90730d4b24974fb077442cdea41c717ca8dd4
Author: Otavio Rodolfo Piske <[email protected]>
AuthorDate: Thu Jun 27 16:49:18 2024 +0200

    CAMEL-19897: another shot at removing isStatisticsEnabled
    
    Signed-off-by: Otavio R. Piske <[email protected]>
---
 .../csimple/joor/OriginalSimpleOperatorTest.java   | 10 ---
 .../camel/component/jcr/JcrConverterTest.java      |  2 +-
 .../camel/spring/xml/CamelContextFactoryBean.java  | 10 +++
 .../apache/camel/spi/TypeConverterRegistry.java    | 17 ++--
 .../camel/impl/engine/AbstractCamelContext.java    |  4 -
 .../camel/impl/engine/SimpleCamelContext.java      |  2 +-
 .../impl/converter/BaseTypeConverterRegistry.java  |  5 +-
 .../camel/impl/converter/ConverterStatistics.java  | 22 ++----
 .../impl/converter/CoreTypeConverterRegistry.java  | 23 +++---
 .../camel/impl/converter/DefaultTypeConverter.java |  8 +-
 .../converter/NoopTypeConverterStatistics.java     | 90 ++++++++++++++++++++++
 .../impl/converter/TypeConverterStatistics.java    | 67 +++++++++-------
 .../camel/impl/console/TypeConverterConsole.java   | 32 ++++----
 .../xml/AbstractCamelContextFactoryBeanTest.java   |  2 +-
 .../org/apache/camel/converter/ConverterTest.java  |  2 +-
 .../java/org/apache/camel/converter/JaxpTest.java  |  4 +-
 .../apache/camel/converter/StringSourceTest.java   |  6 +-
 ...gistryStatisticsEnabledNoStreamCachingTest.java |  7 +-
 ...TypeConverterRegistryStatisticsEnabledTest.java |  4 +-
 .../camel/language/simple/SimpleOperatorTest.java  | 10 ---
 .../mbean/ManagedTypeConverterRegistryMBean.java   |  6 --
 .../mbean/ManagedTypeConverterRegistry.java        | 10 ---
 .../ManagedTypeConverterRegistryTest.java          | 32 ++++----
 .../ROOT/pages/camel-4x-upgrade-guide-4_7.adoc     |  3 +
 .../modules/ROOT/pages/type-converter.adoc         |  4 +
 25 files changed, 227 insertions(+), 155 deletions(-)

diff --git 
a/components/camel-csimple-joor/src/test/java/org/apache/camel/language/csimple/joor/OriginalSimpleOperatorTest.java
 
b/components/camel-csimple-joor/src/test/java/org/apache/camel/language/csimple/joor/OriginalSimpleOperatorTest.java
index 6264b5405b8..51f1cef4ec9 100644
--- 
a/components/camel-csimple-joor/src/test/java/org/apache/camel/language/csimple/joor/OriginalSimpleOperatorTest.java
+++ 
b/components/camel-csimple-joor/src/test/java/org/apache/camel/language/csimple/joor/OriginalSimpleOperatorTest.java
@@ -165,10 +165,6 @@ public class OriginalSimpleOperatorTest extends 
LanguageTestSupport {
         assertPredicate("${in.header.foo} == 'def'", false);
         assertPredicate("${in.header.foo} == '1'", false);
 
-        // no type converter needed from this point forward
-        
context.getTypeConverterRegistry().getStatistics().setStatisticsEnabled(true);
-        context.getTypeConverterRegistry().getStatistics().reset();
-
         // boolean to boolean comparison
         exchange.getIn().setHeader("bool", true);
         exchange.getIn().setHeader("booley", false);
@@ -386,9 +382,6 @@ public class OriginalSimpleOperatorTest extends 
LanguageTestSupport {
 
     @Test
     public void testLessThanOrEqualOperator() {
-        
context.getTypeConverterRegistry().getStatistics().setStatisticsEnabled(true);
-        context.getTypeConverterRegistry().getStatistics().reset();
-
         // string to string comparison
         assertPredicate("${in.header.foo} <= 'aaa'", false);
         assertPredicate("${in.header.foo} <= 'abc'", true);
@@ -413,9 +406,6 @@ public class OriginalSimpleOperatorTest extends 
LanguageTestSupport {
 
     @Test
     public void testTypeCoerceNoConversionNeeded() {
-        
context.getTypeConverterRegistry().getStatistics().setStatisticsEnabled(true);
-        context.getTypeConverterRegistry().getStatistics().reset();
-
         // int to int comparison
         exchange.getIn().setHeader("num", 70);
         assertPredicate("${in.header.num} > 100", false);
diff --git 
a/components/camel-jcr/src/test/java/org/apache/camel/component/jcr/JcrConverterTest.java
 
b/components/camel-jcr/src/test/java/org/apache/camel/component/jcr/JcrConverterTest.java
index 4f6fc8217f9..5a4fde0243b 100644
--- 
a/components/camel-jcr/src/test/java/org/apache/camel/component/jcr/JcrConverterTest.java
+++ 
b/components/camel-jcr/src/test/java/org/apache/camel/component/jcr/JcrConverterTest.java
@@ -73,7 +73,7 @@ public class JcrConverterTest {
                     public boolean supportsAutoWiring() {
                         return false;
                     }
-                }, true);
+                }, true, false);
         ServiceHelper.startService(converter);
     }
 
diff --git 
a/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/CamelContextFactoryBean.java
 
b/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/CamelContextFactoryBean.java
index bdd50cc21cb..03727ab38ab 100644
--- 
a/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/CamelContextFactoryBean.java
+++ 
b/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/CamelContextFactoryBean.java
@@ -519,6 +519,16 @@ public class CamelContextFactoryBean extends 
AbstractCamelContextFactoryBean<Spr
         ctx.setApplicationContext(getApplicationContext());
         ctx.getCamelContextExtension().setName(getId());
 
+        /*
+         * We need to enable the statistics before the type converter is 
created, as
+         * it is immutable in the registry.
+         * Because it's disabled by default, we simply parse the value and 
enable if
+         * it is set to true. Everything else can be ignored.
+         */
+        if (Boolean.parseBoolean(getTypeConverterStatisticsEnabled())) {
+            ctx.setTypeConverterStatisticsEnabled(true);
+        }
+
         return ctx;
     }
 
diff --git 
a/core/camel-api/src/main/java/org/apache/camel/spi/TypeConverterRegistry.java 
b/core/camel-api/src/main/java/org/apache/camel/spi/TypeConverterRegistry.java
index dba59e4d347..979a37acfe3 100644
--- 
a/core/camel-api/src/main/java/org/apache/camel/spi/TypeConverterRegistry.java
+++ 
b/core/camel-api/src/main/java/org/apache/camel/spi/TypeConverterRegistry.java
@@ -16,6 +16,9 @@
  */
 package org.apache.camel.spi;
 
+import java.util.function.LongConsumer;
+import java.util.function.LongSupplier;
+
 import org.apache.camel.CamelContextAware;
 import org.apache.camel.LoggingLevel;
 import org.apache.camel.StaticService;
@@ -66,17 +69,9 @@ public interface TypeConverterRegistry extends 
StaticService, CamelContextAware
          */
         void reset();
 
-        /**
-         * Whether statistics is enabled.
-         */
-        boolean isStatisticsEnabled();
-
-        /**
-         * Sets whether statistics is enabled.
-         *
-         * @param statisticsEnabled <tt>true</tt> to enable
-         */
-        void setStatisticsEnabled(boolean statisticsEnabled);
+        default void computeIfEnabled(LongSupplier supplier, LongConsumer 
consumer) {
+            consumer.accept(supplier.getAsLong());
+        }
     }
 
     /**
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 960b201782d..e4032e1841e 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
@@ -3334,10 +3334,6 @@ public abstract class AbstractCamelContext extends 
BaseService
         getShutdownStrategy();
         getUuidGenerator();
 
-        if (isTypeConverterStatisticsEnabled()) {
-            
getTypeConverterRegistry().getStatistics().setStatisticsEnabled(isTypeConverterStatisticsEnabled());
-        }
-
         // resolve simple language to initialize it
         resolveLanguage("simple");
     }
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 23cf7a44297..ab4bd5e14c0 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
@@ -167,7 +167,7 @@ public class SimpleCamelContext extends 
AbstractCamelContext {
     protected TypeConverter createTypeConverter() {
         return new DefaultTypeConverter(
                 getCamelContextReference(), 
PluginHelper.getPackageScanClassResolver(this), getInjector(),
-                isLoadTypeConverters());
+                isLoadTypeConverters(), isTypeConverterStatisticsEnabled());
     }
 
     @Override
diff --git 
a/core/camel-base/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java
 
b/core/camel-base/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java
index 792d9a21173..cb6617cc3fd 100644
--- 
a/core/camel-base/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java
+++ 
b/core/camel-base/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java
@@ -64,7 +64,10 @@ public abstract class BaseTypeConverterRegistry extends 
CoreTypeConverterRegistr
     protected PackageScanClassResolver resolver;
     protected Injector injector;
 
-    public BaseTypeConverterRegistry(CamelContext camelContext, 
PackageScanClassResolver resolver, Injector injector) {
+    public BaseTypeConverterRegistry(CamelContext camelContext, 
PackageScanClassResolver resolver, Injector injector,
+                                     boolean statisticsEnabled) {
+        super(statisticsEnabled);
+
         this.camelContext = camelContext;
         this.injector = injector;
         this.resolver = resolver;
diff --git 
a/core/camel-base/src/main/java/org/apache/camel/impl/converter/ConverterStatistics.java
 
b/core/camel-base/src/main/java/org/apache/camel/impl/converter/ConverterStatistics.java
index 98127de258e..5348d10037b 100644
--- 
a/core/camel-base/src/main/java/org/apache/camel/impl/converter/ConverterStatistics.java
+++ 
b/core/camel-base/src/main/java/org/apache/camel/impl/converter/ConverterStatistics.java
@@ -18,7 +18,6 @@
 package org.apache.camel.impl.converter;
 
 import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.camel.TypeConverter;
 import org.apache.camel.spi.TypeConverterRegistry;
@@ -29,6 +28,8 @@ import org.apache.camel.spi.TypeConvertible;
  */
 interface ConverterStatistics extends TypeConverterRegistry.Statistics {
 
+    boolean isStatisticsEnabled();
+
     /**
      * Increment the count of failed conversions
      */
@@ -55,21 +56,10 @@ interface ConverterStatistics extends 
TypeConverterRegistry.Statistics {
     void incrementAttempt();
 
     /**
-     * Compute the total number of cached missed conversions
+     * Log the statistics from the converters
      *
-     * @param  converters    the converters cache instance
-     * @param  missConverter the type that represents a type conversion miss
-     * @return               The number of cached missed conversions as an 
AtomicInteger instance
+     * @param converters    the converters cache instance
+     * @param missConverter the type that represents a type conversion miss
      */
-    static AtomicInteger computeCachedMisses(
-            Map<TypeConvertible<?, ?>, TypeConverter> converters, 
TypeConverter missConverter) {
-        AtomicInteger misses = new AtomicInteger();
-
-        converters.forEach((k, v) -> {
-            if (v == missConverter) {
-                misses.incrementAndGet();
-            }
-        });
-        return misses;
-    }
+    void logMappingStatisticsMessage(Map<TypeConvertible<?, ?>, TypeConverter> 
converters, TypeConverter missConverter);
 }
diff --git 
a/core/camel-base/src/main/java/org/apache/camel/impl/converter/CoreTypeConverterRegistry.java
 
b/core/camel-base/src/main/java/org/apache/camel/impl/converter/CoreTypeConverterRegistry.java
index 642132aa7ef..7ea6c911648 100644
--- 
a/core/camel-base/src/main/java/org/apache/camel/impl/converter/CoreTypeConverterRegistry.java
+++ 
b/core/camel-base/src/main/java/org/apache/camel/impl/converter/CoreTypeConverterRegistry.java
@@ -21,7 +21,6 @@ import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.ExecutionException;
-import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.camel.CamelContextAware;
 import org.apache.camel.CamelExecutionException;
@@ -63,7 +62,7 @@ public abstract class CoreTypeConverterRegistry extends 
ServiceSupport implement
     // special enum converter for optional performance
     protected final TypeConverter enumTypeConverter = new EnumTypeConverter();
 
-    private final ConverterStatistics statistics = new 
TypeConverterStatistics();
+    private final ConverterStatistics statistics;
 
     protected TypeConverterExists typeConverterExists = 
TypeConverterExists.Ignore;
     protected LoggingLevel typeConverterExistsLoggingLevel = 
LoggingLevel.DEBUG;
@@ -72,6 +71,14 @@ public abstract class CoreTypeConverterRegistry extends 
ServiceSupport implement
     // space for others added during runtime
     private final Map<TypeConvertible<?, ?>, TypeConverter> converters = new 
ConcurrentHashMap<>(256);
 
+    protected CoreTypeConverterRegistry(boolean statisticsEnabled) {
+        if (statisticsEnabled) {
+            statistics = new TypeConverterStatistics();
+        } else {
+            statistics = new NoopTypeConverterStatistics();
+        }
+    }
+
     @Override
     public boolean allowNull() {
         return false;
@@ -615,21 +622,13 @@ public abstract class CoreTypeConverterRegistry extends 
ServiceSupport implement
     @Override
     protected void doStop() throws Exception {
         super.doStop();
+
         // log utilization statistics when stopping, including mappings
-        if (statistics.isStatisticsEnabled()) {
-            final String info = generateMappingStatisticsMessage();
-            LOG.info(info);
-        }
+        statistics.logMappingStatisticsMessage(converters, MISS_CONVERTER);
 
         statistics.reset();
     }
 
-    private String generateMappingStatisticsMessage() {
-        final AtomicInteger misses = 
ConverterStatistics.computeCachedMisses(converters, MISS_CONVERTER);
-
-        return String.format("%s mappings[total=%s, misses=%s]", statistics, 
size(), misses);
-    }
-
     /**
      * Represents a fallback type converter
      */
diff --git 
a/core/camel-base/src/main/java/org/apache/camel/impl/converter/DefaultTypeConverter.java
 
b/core/camel-base/src/main/java/org/apache/camel/impl/converter/DefaultTypeConverter.java
index 31df118fa3c..c1dee555174 100644
--- 
a/core/camel-base/src/main/java/org/apache/camel/impl/converter/DefaultTypeConverter.java
+++ 
b/core/camel-base/src/main/java/org/apache/camel/impl/converter/DefaultTypeConverter.java
@@ -40,13 +40,13 @@ public class DefaultTypeConverter extends 
BaseTypeConverterRegistry implements A
     private final boolean loadTypeConverters;
 
     public DefaultTypeConverter(PackageScanClassResolver resolver, Injector 
injector,
-                                boolean loadTypeConverters) {
-        this(null, resolver, injector, loadTypeConverters);
+                                boolean loadTypeConverters, boolean 
statisticsEnabled) {
+        this(null, resolver, injector, loadTypeConverters, statisticsEnabled);
     }
 
     public DefaultTypeConverter(CamelContext camelContext, 
PackageScanClassResolver resolver, Injector injector,
-                                boolean loadTypeConverters) {
-        super(camelContext, resolver, injector);
+                                boolean loadTypeConverters, boolean 
statisticsEnabled) {
+        super(camelContext, resolver, injector, statisticsEnabled);
         this.loadTypeConverters = loadTypeConverters;
     }
 
diff --git 
a/core/camel-base/src/main/java/org/apache/camel/impl/converter/NoopTypeConverterStatistics.java
 
b/core/camel-base/src/main/java/org/apache/camel/impl/converter/NoopTypeConverterStatistics.java
new file mode 100644
index 00000000000..6f596a49222
--- /dev/null
+++ 
b/core/camel-base/src/main/java/org/apache/camel/impl/converter/NoopTypeConverterStatistics.java
@@ -0,0 +1,90 @@
+/*
+ * 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.converter;
+
+import java.util.Map;
+
+import org.apache.camel.TypeConverter;
+import org.apache.camel.spi.TypeConvertible;
+
+final class NoopTypeConverterStatistics implements ConverterStatistics {
+    @Override
+    public long getNoopCounter() {
+        return 0;
+    }
+
+    @Override
+    public long getAttemptCounter() {
+        return 0;
+    }
+
+    @Override
+    public long getHitCounter() {
+        return 0;
+    }
+
+    @Override
+    public long getMissCounter() {
+        return 0;
+    }
+
+    @Override
+    public long getFailedCounter() {
+        return 0;
+    }
+
+    @Override
+    public void reset() {
+        // NO-OP
+    }
+
+    @Override
+    public boolean isStatisticsEnabled() {
+        return false;
+    }
+
+    @Override
+    public void incrementFailed() {
+        // NO-OP
+    }
+
+    @Override
+    public void incrementNoop() {
+        // NO-OP
+    }
+
+    @Override
+    public void incrementHit() {
+        // NO-OP
+    }
+
+    @Override
+    public void incrementMiss() {
+        // NO-OP
+    }
+
+    @Override
+    public void incrementAttempt() {
+        // NO-OP
+    }
+
+    @Override
+    public void logMappingStatisticsMessage(Map<TypeConvertible<?, ?>, 
TypeConverter> converters, TypeConverter missConverter) {
+        // NO-OP
+    }
+}
diff --git 
a/core/camel-base/src/main/java/org/apache/camel/impl/converter/TypeConverterStatistics.java
 
b/core/camel-base/src/main/java/org/apache/camel/impl/converter/TypeConverterStatistics.java
index 2a813d6a26e..9360f6acc5c 100644
--- 
a/core/camel-base/src/main/java/org/apache/camel/impl/converter/TypeConverterStatistics.java
+++ 
b/core/camel-base/src/main/java/org/apache/camel/impl/converter/TypeConverterStatistics.java
@@ -17,14 +17,21 @@
 
 package org.apache.camel.impl.converter;
 
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.LongAdder;
 
+import org.apache.camel.TypeConverter;
+import org.apache.camel.spi.TypeConvertible;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 /**
  * Represents utilization statistics
  */
 final class TypeConverterStatistics implements ConverterStatistics {
+    private static final Logger LOG = 
LoggerFactory.getLogger(TypeConverterStatistics.class);
 
-    private boolean statisticsEnabled;
     private final LongAdder noopCounter = new LongAdder();
     private final LongAdder attemptCounter = new LongAdder();
     private final LongAdder missCounter = new LongAdder();
@@ -56,39 +63,34 @@ final class TypeConverterStatistics implements 
ConverterStatistics {
         return failedCounter.longValue();
     }
 
+    @Override
+    public boolean isStatisticsEnabled() {
+        return true;
+    }
+
     @Override
     public void incrementFailed() {
-        if (statisticsEnabled) {
-            failedCounter.increment();
-        }
+        failedCounter.increment();
     }
 
     @Override
     public void incrementNoop() {
-        if (statisticsEnabled) {
-            noopCounter.increment();
-        }
+        noopCounter.increment();
     }
 
     @Override
     public void incrementHit() {
-        if (statisticsEnabled) {
-            hitCounter.increment();
-        }
+        hitCounter.increment();
     }
 
     @Override
     public void incrementMiss() {
-        if (statisticsEnabled) {
-            missCounter.increment();
-        }
+        missCounter.increment();
     }
 
     @Override
     public void incrementAttempt() {
-        if (statisticsEnabled) {
-            attemptCounter.increment();
-        }
+        attemptCounter.increment();
     }
 
     @Override
@@ -100,19 +102,32 @@ final class TypeConverterStatistics implements 
ConverterStatistics {
         failedCounter.reset();
     }
 
-    @Override
-    public boolean isStatisticsEnabled() {
-        return statisticsEnabled;
+    /**
+     * Compute the total number of cached missed conversions
+     *
+     * @param  converters    the converters cache instance
+     * @param  missConverter the type that represents a type conversion miss
+     * @return               The number of cached missed conversions as an 
AtomicInteger instance
+     */
+    private static AtomicInteger computeCachedMisses(
+            Map<TypeConvertible<?, ?>, TypeConverter> converters, 
TypeConverter missConverter) {
+        AtomicInteger misses = new AtomicInteger();
+
+        converters.forEach((k, v) -> {
+            if (v == missConverter) {
+                misses.incrementAndGet();
+            }
+        });
+        return misses;
     }
 
     @Override
-    public void setStatisticsEnabled(boolean statisticsEnabled) {
-        this.statisticsEnabled = statisticsEnabled;
-    }
+    public void logMappingStatisticsMessage(Map<TypeConvertible<?, ?>, 
TypeConverter> converters, TypeConverter missConverter) {
+        final AtomicInteger misses = computeCachedMisses(converters, 
missConverter);
 
-    @Override
-    public String toString() {
-        return String.format("TypeConverterRegistry utilization[noop=%s, 
attempts=%s, hits=%s, misses=%s, failures=%s]",
-                getNoopCounter(), getAttemptCounter(), getHitCounter(), 
getMissCounter(), getFailedCounter());
+        LOG.info(
+                "TypeConverterStatistics utilization[noop={}, attempts={}, 
hits={}, misses={}, failures={}] mappings[total={}, misses={}]",
+                getNoopCounter(), getAttemptCounter(), getHitCounter(), 
getMissCounter(), getFailedCounter(), converters.size(),
+                misses);
     }
 }
diff --git 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/TypeConverterConsole.java
 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/TypeConverterConsole.java
index c13365853c9..4aea4072a22 100644
--- 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/TypeConverterConsole.java
+++ 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/TypeConverterConsole.java
@@ -38,13 +38,13 @@ public class TypeConverterConsole extends 
AbstractDevConsole {
         sb.append(String.format("\n    Converters: %s", reg.size()));
         sb.append(String.format("\n    Exists: %s", 
reg.getTypeConverterExists().name()));
         sb.append(String.format("\n    Exists LoggingLevel: %s", 
reg.getTypeConverterExistsLoggingLevel()));
-        if (reg.getStatistics().isStatisticsEnabled()) {
-            sb.append(String.format("\n    Attempts: %s", 
reg.getStatistics().getAttemptCounter()));
-            sb.append(String.format("\n    Hit: %s", 
reg.getStatistics().getHitCounter()));
-            sb.append(String.format("\n    Miss: %s", 
reg.getStatistics().getMissCounter()));
-            sb.append(String.format("\n    Failed: %s", 
reg.getStatistics().getFailedCounter()));
-            sb.append(String.format("\n    Noop: %s", 
reg.getStatistics().getNoopCounter()));
-        }
+        final TypeConverterRegistry.Statistics statistics = 
reg.getStatistics();
+
+        statistics.computeIfEnabled(statistics::getAttemptCounter, v -> 
sb.append(String.format("\n    Attempts: %s", v)));
+        statistics.computeIfEnabled(statistics::getHitCounter, v -> 
sb.append(String.format("\n    Hit: %s", v)));
+        statistics.computeIfEnabled(statistics::getMissCounter, v -> 
sb.append(String.format("\n    Miss: %s", v)));
+        statistics.computeIfEnabled(statistics::getFailedCounter, v -> 
sb.append(String.format("\n    Failed: %s", v)));
+        statistics.computeIfEnabled(statistics::getNoopCounter, v -> 
sb.append(String.format("\n    Noop: %s", v)));
 
         return sb.toString();
     }
@@ -57,14 +57,18 @@ public class TypeConverterConsole extends 
AbstractDevConsole {
         root.put("size", reg.size());
         root.put("exists", reg.getTypeConverterExists().name());
         root.put("existsLoggingLevel", 
reg.getTypeConverterExistsLoggingLevel().name());
-        if (reg.getStatistics().isStatisticsEnabled()) {
-            JsonObject props = new JsonObject();
+
+        final TypeConverterRegistry.Statistics statistics = 
reg.getStatistics();
+        JsonObject props = new JsonObject();
+
+        statistics.computeIfEnabled(statistics::getAttemptCounter, v -> 
props.put("attemptCounter", v));
+        statistics.computeIfEnabled(statistics::getHitCounter, v -> 
props.put("hitCounter", v));
+        statistics.computeIfEnabled(statistics::getMissCounter, v -> 
props.put("missCounter", v));
+        statistics.computeIfEnabled(statistics::getFailedCounter, v -> 
props.put("failedCounter", v));
+        statistics.computeIfEnabled(statistics::getFailedCounter, v -> 
props.put("noopCounter", v));
+
+        if (!props.isEmpty()) {
             root.put("statistics", props);
-            props.put("attemptCounter", 
reg.getStatistics().getAttemptCounter());
-            props.put("hitCounter", reg.getStatistics().getHitCounter());
-            props.put("missCounter", reg.getStatistics().getAttemptCounter());
-            props.put("failedCounter", reg.getStatistics().getFailedCounter());
-            props.put("noopCounter", reg.getStatistics().getNoopCounter());
         }
 
         return root;
diff --git 
a/core/camel-core-xml/src/test/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBeanTest.java
 
b/core/camel-core-xml/src/test/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBeanTest.java
index 4d2165d05fc..c8ac3be4565 100644
--- 
a/core/camel-core-xml/src/test/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBeanTest.java
+++ 
b/core/camel-core-xml/src/test/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBeanTest.java
@@ -85,7 +85,7 @@ public class AbstractCamelContextFactoryBeanTest {
                 public boolean supportsAutoWiring() {
                     return false;
                 }
-            }, false);
+            }, false, false);
 
     // properties that should return value that can be converted to boolean
     final Set<String> valuesThatReturnBoolean = new HashSet<>(
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/converter/ConverterTest.java 
b/core/camel-core/src/test/java/org/apache/camel/converter/ConverterTest.java
index 317c382b134..0c890ed5899 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/converter/ConverterTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/converter/ConverterTest.java
@@ -58,7 +58,7 @@ public class ConverterTest extends TestSupport {
     private static final Logger LOG = 
LoggerFactory.getLogger(ConverterTest.class);
 
     protected final TypeConverter converter = new DefaultTypeConverter(
-            new DefaultPackageScanClassResolver(), new ReflectionInjector(), 
true);
+            new DefaultPackageScanClassResolver(), new ReflectionInjector(), 
true, false);
 
     @BeforeEach
     public void setUp() {
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/converter/JaxpTest.java 
b/core/camel-core/src/test/java/org/apache/camel/converter/JaxpTest.java
index 3d46730d9b0..8d93590bb23 100644
--- a/core/camel-core/src/test/java/org/apache/camel/converter/JaxpTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/converter/JaxpTest.java
@@ -40,8 +40,8 @@ import static org.junit.jupiter.api.Assertions.*;
 
 public class JaxpTest {
     private static final Logger LOG = LoggerFactory.getLogger(JaxpTest.class);
-    protected final TypeConverter converter = new DefaultTypeConverter(
-            new DefaultPackageScanClassResolver(), new ReflectionInjector(), 
false);
+    protected TypeConverter converter = new DefaultTypeConverter(
+            new DefaultPackageScanClassResolver(), new ReflectionInjector(), 
false, false);
 
     @BeforeEach
     public void setUp() {
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/converter/StringSourceTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/converter/StringSourceTest.java
index fbae0561a26..f10c71a8ce9 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/converter/StringSourceTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/converter/StringSourceTest.java
@@ -34,9 +34,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 public class StringSourceTest {
-    protected final TypeConverter converter = new DefaultTypeConverter(
-            new DefaultPackageScanClassResolver(), new ReflectionInjector(), 
false);
-    protected final String expectedBody = "<hello>world!</hello>";
+    protected TypeConverter converter = new DefaultTypeConverter(
+            new DefaultPackageScanClassResolver(), new ReflectionInjector(), 
false, false);
+    protected String expectedBody = "<hello>world!</hello>";
 
     @BeforeEach
     public void setUp() {
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/impl/TypeConverterRegistryStatisticsEnabledNoStreamCachingTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/impl/TypeConverterRegistryStatisticsEnabledNoStreamCachingTest.java
index 7ed2021b316..28eb84d61b5 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/impl/TypeConverterRegistryStatisticsEnabledNoStreamCachingTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/impl/TypeConverterRegistryStatisticsEnabledNoStreamCachingTest.java
@@ -24,15 +24,17 @@ import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
 
 public class TypeConverterRegistryStatisticsEnabledNoStreamCachingTest extends 
ContextTestSupport {
 
     @Override
     protected CamelContext createCamelContext() throws Exception {
-        CamelContext context = super.createCamelContext();
+        CamelContext context = new DefaultCamelContext(false);
+        context.setLoadTypeConverters(isLoadTypeConverters());
         context.setStreamCaching(false);
         context.setTypeConverterStatisticsEnabled(true);
+        context.build();
+
         return context;
     }
 
@@ -46,7 +48,6 @@ public class 
TypeConverterRegistryStatisticsEnabledNoStreamCachingTest extends C
         assertMockEndpointsSatisfied();
 
         TypeConverterRegistry reg = context.getTypeConverterRegistry();
-        assertTrue(reg.getStatistics().isStatisticsEnabled(), "Should be 
enabled");
 
         long failed = reg.getStatistics().getFailedCounter();
         assertEquals(0, (int) failed);
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/impl/TypeConverterRegistryStatisticsEnabledTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/impl/TypeConverterRegistryStatisticsEnabledTest.java
index 43fd212c596..0a9dec58add 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/impl/TypeConverterRegistryStatisticsEnabledTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/impl/TypeConverterRegistryStatisticsEnabledTest.java
@@ -24,13 +24,12 @@ import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
 
 public class TypeConverterRegistryStatisticsEnabledTest extends 
ContextTestSupport {
 
     @Override
     protected CamelContext createCamelContext() throws Exception {
-        CamelContext context = super.createCamelContext();
+        CamelContext context = new DefaultCamelContext(false);
         context.setTypeConverterStatisticsEnabled(true);
         return context;
     }
@@ -45,7 +44,6 @@ public class TypeConverterRegistryStatisticsEnabledTest 
extends ContextTestSuppo
         assertMockEndpointsSatisfied();
 
         TypeConverterRegistry reg = context.getTypeConverterRegistry();
-        assertTrue(reg.getStatistics().isStatisticsEnabled(), "Should be 
enabled");
 
         long failed = reg.getStatistics().getFailedCounter();
         assertEquals(0, (int) failed);
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleOperatorTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleOperatorTest.java
index 00d20a9cfad..74c491c1185 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleOperatorTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleOperatorTest.java
@@ -173,10 +173,6 @@ public class SimpleOperatorTest extends 
LanguageTestSupport {
         assertPredicate("${in.header.foo} == '-'", false);
         assertPredicate("${in.header.bar} == '-'", false);
 
-        // no type converter needed from this point forward
-        
context.getTypeConverterRegistry().getStatistics().setStatisticsEnabled(true);
-        context.getTypeConverterRegistry().getStatistics().reset();
-
         // boolean to boolean comparison
         exchange.getIn().setHeader("bool", true);
         exchange.getIn().setHeader("booley", false);
@@ -406,9 +402,6 @@ public class SimpleOperatorTest extends LanguageTestSupport 
{
 
     @Test
     public void testLessThanOrEqualOperator() {
-        
context.getTypeConverterRegistry().getStatistics().setStatisticsEnabled(true);
-        context.getTypeConverterRegistry().getStatistics().reset();
-
         // string to string comparison
         assertPredicate("${in.header.foo} <= 'aaa'", false);
         assertPredicate("${in.header.foo} <= 'abc'", true);
@@ -433,9 +426,6 @@ public class SimpleOperatorTest extends LanguageTestSupport 
{
 
     @Test
     public void testTypeCoerceNoConversionNeeded() {
-        
context.getTypeConverterRegistry().getStatistics().setStatisticsEnabled(true);
-        context.getTypeConverterRegistry().getStatistics().reset();
-
         // int to int comparison
         exchange.getIn().setHeader("num", 70);
         assertPredicate("${in.header.num} > 100", false);
diff --git 
a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedTypeConverterRegistryMBean.java
 
b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedTypeConverterRegistryMBean.java
index f607a3652bb..1ca1550b14d 100644
--- 
a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedTypeConverterRegistryMBean.java
+++ 
b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedTypeConverterRegistryMBean.java
@@ -39,12 +39,6 @@ public interface ManagedTypeConverterRegistryMBean extends 
ManagedServiceMBean {
     @ManagedOperation(description = "Resets the type conversion counters")
     void resetTypeConversionCounters();
 
-    @ManagedAttribute(description = "Utilization statistics enabled")
-    boolean isStatisticsEnabled();
-
-    @ManagedAttribute(description = "Utilization statistics enabled")
-    void setStatisticsEnabled(boolean statisticsEnabled);
-
     @ManagedAttribute(description = "Number of type converters in the 
registry")
     int getNumberOfTypeConverters();
 
diff --git 
a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedTypeConverterRegistry.java
 
b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedTypeConverterRegistry.java
index 16d31164bf3..c6a51fbbd1d 100644
--- 
a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedTypeConverterRegistry.java
+++ 
b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedTypeConverterRegistry.java
@@ -69,16 +69,6 @@ public class ManagedTypeConverterRegistry extends 
ManagedService implements Mana
         registry.getStatistics().reset();
     }
 
-    @Override
-    public boolean isStatisticsEnabled() {
-        return registry.getStatistics().isStatisticsEnabled();
-    }
-
-    @Override
-    public void setStatisticsEnabled(boolean statisticsEnabled) {
-        registry.getStatistics().setStatisticsEnabled(statisticsEnabled);
-    }
-
     @Override
     public int getNumberOfTypeConverters() {
         return registry.size();
diff --git 
a/core/camel-management/src/test/java/org/apache/camel/management/ManagedTypeConverterRegistryTest.java
 
b/core/camel-management/src/test/java/org/apache/camel/management/ManagedTypeConverterRegistryTest.java
index 20eec2bbe19..5f91f325353 100644
--- 
a/core/camel-management/src/test/java/org/apache/camel/management/ManagedTypeConverterRegistryTest.java
+++ 
b/core/camel-management/src/test/java/org/apache/camel/management/ManagedTypeConverterRegistryTest.java
@@ -18,21 +18,33 @@ package org.apache.camel.management;
 
 import java.util.Set;
 
-import javax.management.Attribute;
 import javax.management.MBeanServer;
 import javax.management.ObjectName;
 
+import org.apache.camel.CamelContext;
 import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.DefaultCamelContext;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.condition.DisabledOnOs;
 import org.junit.jupiter.api.condition.OS;
 
 import static 
org.apache.camel.management.DefaultManagementObjectNameStrategy.TYPE_SERVICE;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
 
 @DisabledOnOs(OS.AIX)
 public class ManagedTypeConverterRegistryTest extends ManagementTestSupport {
 
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext context = new DefaultCamelContext(false);
+        context.setTypeConverterStatisticsEnabled(true);
+        return context;
+    }
+
     @Test
     public void testTypeConverterRegistry() throws Exception {
         getMockEndpoint("mock:a").expectedMessageCount(2);
@@ -57,18 +69,6 @@ public class ManagedTypeConverterRegistryTest extends 
ManagementTestSupport {
         }
         assertNotNull(name, "Cannot find DefaultTypeConverter");
 
-        // is disabled by default
-        Boolean enabled = (Boolean) mbeanServer.getAttribute(name, 
"StatisticsEnabled");
-        assertEquals(Boolean.FALSE, enabled);
-
-        // need to enable statistics
-        mbeanServer.setAttribute(name, new Attribute("StatisticsEnabled", 
Boolean.TRUE));
-
-        Long failed = (Long) mbeanServer.getAttribute(name, "FailedCounter");
-        assertEquals(0, failed.intValue());
-        Long miss = (Long) mbeanServer.getAttribute(name, "MissCounter");
-        assertEquals(0, miss.intValue());
-
         // reset
         mbeanServer.invoke(name, "resetTypeConversionCounters", null, null);
 
@@ -77,9 +77,9 @@ public class ManagedTypeConverterRegistryTest extends 
ManagementTestSupport {
         // should hit
         Long hit = (Long) mbeanServer.getAttribute(name, "HitCounter");
         assertEquals(1, hit.intValue());
-        failed = (Long) mbeanServer.getAttribute(name, "FailedCounter");
+        Long failed = (Long) mbeanServer.getAttribute(name, "FailedCounter");
         assertEquals(0, failed.intValue());
-        miss = (Long) mbeanServer.getAttribute(name, "MissCounter");
+        Long miss = (Long) mbeanServer.getAttribute(name, "MissCounter");
         assertEquals(2, miss.intValue());  // stream caching misses
 
         // reset
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_7.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_7.adoc
index 4c78cfff977..16c5e719385 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_7.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_7.adoc
@@ -21,6 +21,9 @@ Add default values to `ThrottlingExceptionRoutePolicy` route 
policy.
 The `EndpointRegistry` interface has been slightly changed to now directly 
extends `Map<NormalizedEndpointUri, Endpoint>` 
 instead of being a parameterized type. This may cause some compilation 
failures if the code is declaring a variable for the registry.
 
+The statistics collector in the registry has been made immutable. As such, 
enabling collection of statistics has to be done
+prior to creating the type converter registry
+
 === camel-health
 
 Routes which has are set to **not** auto-startup are reported as UP in 
health-checks.
diff --git a/docs/user-manual/modules/ROOT/pages/type-converter.adoc 
b/docs/user-manual/modules/ROOT/pages/type-converter.adoc
index 23daa6ebe5a..7b5940baaba 100644
--- a/docs/user-manual/modules/ROOT/pages/type-converter.adoc
+++ b/docs/user-manual/modules/ROOT/pages/type-converter.adoc
@@ -71,6 +71,10 @@ and invoke these type converters at runtime via quick Java 
method invocations (n
 
 === Type converter registry utilization statistics
 
+NOTE: as of Camel 4.7.0, the statistics collector in the registry has been 
made immutable.
+As such, enabling collection of statistics has to be done prior to creating 
the type converter
+registry.
+
 Camel can gather utilization statistics of the runtime usage of type
 converters. These statistics are available in xref:jmx.adoc[JMX] as well as
 from 
https://www.javadoc.io/doc/org.apache.camel/camel-api/latest/org/apache/camel/spi/TypeConverterRegistry.html#getStatistics--[`TypeConverterRegistry#getStatistics()`].


Reply via email to