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 5f672e435cf CAMEL-19405: Loading custom dev console should be able to hot-reload such as via camel-jbang 5f672e435cf is described below commit 5f672e435cf868a51132a843af1014fe59729773 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Wed May 31 19:08:44 2023 +0200 CAMEL-19405: Loading custom dev console should be able to hot-reload such as via camel-jbang --- .../org/apache/camel/console/DevConsoleResolver.java | 3 ++- .../main/java/org/apache/camel/spi/FactoryFinder.java | 5 +++++ .../apache/camel/impl/engine/BootstrapFactoryFinder.java | 16 ++++------------ .../camel/impl/engine/DefaultDevConsoleResolver.java | 15 ++++++++++++++- .../apache/camel/impl/engine/DefaultFactoryFinder.java | 15 +++++++++++++-- .../camel/impl/console/DefaultDevConsoleRegistry.java | 2 +- .../camel/impl/console/DefaultDevConsolesLoader.java | 13 +++++++++++-- .../camel/impl/console/DefaultDevConsolesLoaderTest.java | 8 ++++++++ 8 files changed, 58 insertions(+), 19 deletions(-) diff --git a/core/camel-api/src/main/java/org/apache/camel/console/DevConsoleResolver.java b/core/camel-api/src/main/java/org/apache/camel/console/DevConsoleResolver.java index 8894bd942da..4ff39eff4ec 100644 --- a/core/camel-api/src/main/java/org/apache/camel/console/DevConsoleResolver.java +++ b/core/camel-api/src/main/java/org/apache/camel/console/DevConsoleResolver.java @@ -19,11 +19,12 @@ package org.apache.camel.console; import java.util.Optional; import org.apache.camel.CamelContextAware; +import org.apache.camel.StaticService; /** * A pluggable strategy for resolving dev consoles in a loosely coupled manner */ -public interface DevConsoleResolver extends CamelContextAware { +public interface DevConsoleResolver extends CamelContextAware, StaticService { /** * Resolves the given {@link DevConsole}. diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/FactoryFinder.java b/core/camel-api/src/main/java/org/apache/camel/spi/FactoryFinder.java index dec47d2a486..91af20a08a4 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/FactoryFinder.java +++ b/core/camel-api/src/main/java/org/apache/camel/spi/FactoryFinder.java @@ -65,4 +65,9 @@ public interface FactoryFinder { */ Optional<Class<?>> findOptionalClass(String key); + /** + * Clear the resolver state from previous scans. + */ + void clear(); + } diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/BootstrapFactoryFinder.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/BootstrapFactoryFinder.java index cd595c38064..06d415a2aba 100644 --- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/BootstrapFactoryFinder.java +++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/BootstrapFactoryFinder.java @@ -30,18 +30,10 @@ public class BootstrapFactoryFinder extends DefaultFactoryFinder implements Boot @Override public void close() { + clear(); classResolver = null; - if (classMap != null) { - classMap.clear(); - classMap = null; - } - if (classesNotFound != null) { - classesNotFound.clear(); - classesNotFound = null; - } - if (classesNotFoundExceptions != null) { - classesNotFoundExceptions.clear(); - classesNotFoundExceptions = null; - } + classMap = null; + classesNotFound = null; + classesNotFoundExceptions = null; } } diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultDevConsoleResolver.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultDevConsoleResolver.java index f1ff725b2e8..17fda0ea627 100644 --- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultDevConsoleResolver.java +++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultDevConsoleResolver.java @@ -25,12 +25,13 @@ import org.apache.camel.console.DevConsole; import org.apache.camel.console.DevConsoleRegistry; import org.apache.camel.console.DevConsoleResolver; import org.apache.camel.spi.FactoryFinder; +import org.apache.camel.support.service.ServiceSupport; /** * Default dev console resolver that looks for dev consoles factories in * <b>META-INF/services/org/apache/camel/dev-console/</b>. */ -public class DefaultDevConsoleResolver implements DevConsoleResolver, CamelContextAware { +public class DefaultDevConsoleResolver extends ServiceSupport implements DevConsoleResolver, CamelContextAware { public static final String DEV_CONSOLE_RESOURCE_PATH = "META-INF/services/org/apache/camel/dev-console/"; @@ -97,4 +98,16 @@ public class DefaultDevConsoleResolver implements DevConsoleResolver, CamelConte return Optional.empty(); } } + + @Override + protected void doStart() throws Exception { + // noop + } + + @Override + protected void doStop() throws Exception { + if (devConsoleFactory != null) { + devConsoleFactory.clear(); + } + } } diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultFactoryFinder.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultFactoryFinder.java index 01649342f6d..0e2d3a25eaf 100644 --- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultFactoryFinder.java +++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultFactoryFinder.java @@ -65,7 +65,6 @@ public class DefaultFactoryFinder implements FactoryFinder { @Override public Optional<Class<?>> findClass(String key) { - Class<?> clazz = addToClassMap(key, () -> { Properties prop = doFindFactoryProperties(key); if (prop != null) { @@ -79,7 +78,6 @@ public class DefaultFactoryFinder implements FactoryFinder { @Override public Optional<Class<?>> findOptionalClass(String key) { - Class<?> clazz = addToClassMap(key, () -> { Properties prop = doFindFactoryProperties(key); if (prop != null) { @@ -91,6 +89,19 @@ public class DefaultFactoryFinder implements FactoryFinder { return Optional.ofNullable(clazz); } + @Override + public void clear() { + if (classMap != null) { + classMap.clear(); + } + if (classesNotFound != null) { + classesNotFound.clear(); + } + if (classesNotFoundExceptions != null) { + classesNotFoundExceptions.clear(); + } + } + private Object doNewInstance(String key) { Optional<Class<?>> clazz = findClass(key); return clazz.map(ObjectHelper::newInstance).orElse(null); diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/DefaultDevConsoleRegistry.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/DefaultDevConsoleRegistry.java index ad59c206b3f..fe949636fdb 100644 --- a/core/camel-console/src/main/java/org/apache/camel/impl/console/DefaultDevConsoleRegistry.java +++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/DefaultDevConsoleRegistry.java @@ -177,7 +177,7 @@ public class DefaultDevConsoleRegistry extends ServiceSupport implements DevCons loadDevConsolesDone = true; DefaultDevConsolesLoader loader = new DefaultDevConsolesLoader(camelContext); - Collection<DevConsole> col = loader.loadDevConsoles(); + Collection<DevConsole> col = loader.loadDevConsoles(force); if (!col.isEmpty()) { int added = 0; diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/DefaultDevConsolesLoader.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/DefaultDevConsolesLoader.java index 7c640a59894..5390804347d 100644 --- a/core/camel-console/src/main/java/org/apache/camel/impl/console/DefaultDevConsolesLoader.java +++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/DefaultDevConsolesLoader.java @@ -25,6 +25,7 @@ import org.apache.camel.console.DevConsoleResolver; import org.apache.camel.spi.PackageScanResourceResolver; import org.apache.camel.spi.Resource; import org.apache.camel.support.PluginHelper; +import org.apache.camel.support.service.ServiceHelper; import org.apache.camel.util.StringHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,11 +49,19 @@ public class DefaultDevConsolesLoader { } public Collection<DevConsole> loadDevConsoles() { - Collection<DevConsole> answer = new ArrayList<>(); + return loadDevConsoles(false); + } - LOG.trace("Searching for {} dev consoles", META_INF_SERVICES); + public Collection<DevConsole> loadDevConsoles(boolean force) { + Collection<DevConsole> answer = new ArrayList<>(); + if (force) { + // when forcing then restart resolver, so we can do a re-scan + ServiceHelper.stopService(devConsoleResolver); + ServiceHelper.startService(devConsoleResolver); + } try { + LOG.trace("Searching for {} dev consoles", META_INF_SERVICES); Collection<Resource> resources = resolver.findResources(META_INF_SERVICES + "/*"); if (LOG.isDebugEnabled()) { LOG.debug("Discovered {} dev consoles from classpath scanning", resources.size()); diff --git a/core/camel-console/src/test/java/org/apache/camel/impl/console/DefaultDevConsolesLoaderTest.java b/core/camel-console/src/test/java/org/apache/camel/impl/console/DefaultDevConsolesLoaderTest.java index 3f768ed11e7..cba66da74d8 100644 --- a/core/camel-console/src/test/java/org/apache/camel/impl/console/DefaultDevConsolesLoaderTest.java +++ b/core/camel-console/src/test/java/org/apache/camel/impl/console/DefaultDevConsolesLoaderTest.java @@ -31,4 +31,12 @@ public class DefaultDevConsolesLoaderTest extends ContextTestSupport { Collection<DevConsole> col = loader.loadDevConsoles(); Assertions.assertTrue(col.size() > 3); } + + @Test + public void testLoaderForce() throws Exception { + DefaultDevConsolesLoader loader = new DefaultDevConsolesLoader(context); + Collection<DevConsole> col = loader.loadDevConsoles(true); + Assertions.assertTrue(col.size() > 3); + } + }