This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch console in repository https://gitbox.apache.org/repos/asf/camel.git
commit d054019e72a3afde08b6d84352d9865b654b748f Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Mon Dec 27 11:52:27 2021 +0100 CAMEL-17384: Developer Console SPI --- .../org/apache/camel/ExtendedCamelContext.java | 15 ++++ .../apache/camel/console/DevConsoleResolver.java | 34 +++++++++ .../camel/impl/engine/AbstractCamelContext.java | 19 +++++ .../impl/engine/DefaultDevConsoleResolver.java | 88 ++++++++++++++++++++++ .../camel/impl/engine/SimpleCamelContext.java | 6 ++ .../camel/impl/ExtendedCamelContextConfigurer.java | 6 ++ .../camel/impl/lw/LightweightCamelContext.java | 11 +++ .../impl/lw/LightweightRuntimeCamelContext.java | 13 ++++ 8 files changed, 192 insertions(+) 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 26a029b..c13ff57 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 @@ -22,6 +22,7 @@ import java.util.Set; import java.util.concurrent.ScheduledExecutorService; import org.apache.camel.catalog.RuntimeCamelCatalog; +import org.apache.camel.console.DevConsoleResolver; import org.apache.camel.health.HealthCheckResolver; import org.apache.camel.spi.AnnotationBasedProcessorFactory; import org.apache.camel.spi.AsyncProcessorAwaitManager; @@ -350,6 +351,20 @@ public interface ExtendedCamelContext extends CamelContext { void setHealthCheckResolver(HealthCheckResolver healthCheckResolver); /** + * Gets the current dev console resolver + * + * @return the resolver + */ + DevConsoleResolver getDevConsoleResolver(); + + /** + * Sets a custom dev console resolver + * + * @param devConsoleResolver the resolver + */ + void setDevConsoleResolver(DevConsoleResolver devConsoleResolver); + + /** * Returns the package scanning class resolver * * @return the resolver 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 new file mode 100644 index 0000000..bae9ca0 --- /dev/null +++ b/core/camel-api/src/main/java/org/apache/camel/console/DevConsoleResolver.java @@ -0,0 +1,34 @@ +/* + * 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.console; + +import org.apache.camel.CamelContextAware; + +/** + * A pluggable strategy for resolving dev consoles in a loosely coupled manner + */ +public interface DevConsoleResolver extends CamelContextAware { + + /** + * Resolves the given {@link DevConsole}. + * + * @param id the id of the {@link DevConsole} + * @return the resolved {@link DevConsole}, or <tt>null</tt> if not found + */ + DevConsole resolveDevConsole(String id); + +} 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 df4e243..63ad43d 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 @@ -80,6 +80,7 @@ import org.apache.camel.TypeConverter; import org.apache.camel.VetoCamelContextStartException; import org.apache.camel.api.management.JmxSystemPropertyKeys; import org.apache.camel.catalog.RuntimeCamelCatalog; +import org.apache.camel.console.DevConsoleResolver; import org.apache.camel.health.HealthCheckRegistry; import org.apache.camel.health.HealthCheckResolver; import org.apache.camel.spi.AnnotationBasedProcessorFactory; @@ -294,6 +295,7 @@ public abstract class AbstractCamelContext extends BaseService private volatile UriFactoryResolver uriFactoryResolver; private volatile DataFormatResolver dataFormatResolver; private volatile HealthCheckResolver healthCheckResolver; + private volatile DevConsoleResolver devConsoleResolver; private volatile ManagementStrategy managementStrategy; private volatile ManagementMBeanAssembler managementMBeanAssembler; private volatile RestRegistryFactory restRegistryFactory; @@ -4366,6 +4368,21 @@ public abstract class AbstractCamelContext extends BaseService this.healthCheckResolver = doAddService(healthCheckResolver); } + public DevConsoleResolver getDevConsoleResolver() { + if (devConsoleResolver == null) { + synchronized (lock) { + if (devConsoleResolver == null) { + setDevConsoleResolver(createDevConsoleResolver()); + } + } + } + return devConsoleResolver; + } + + public void setDevConsoleResolver(DevConsoleResolver devConsoleResolver) { + this.devConsoleResolver = devConsoleResolver; + } + @Override public ShutdownStrategy getShutdownStrategy() { if (shutdownStrategy == null) { @@ -5064,6 +5081,8 @@ public abstract class AbstractCamelContext extends BaseService protected abstract HealthCheckResolver createHealthCheckResolver(); + protected abstract DevConsoleResolver createDevConsoleResolver(); + protected abstract MessageHistoryFactory createMessageHistoryFactory(); protected abstract InflightRepository createInflightRepository(); 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 new file mode 100644 index 0000000..6efc9ab --- /dev/null +++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultDevConsoleResolver.java @@ -0,0 +1,88 @@ +/* + * 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.engine; + +import org.apache.camel.CamelContext; +import org.apache.camel.CamelContextAware; +import org.apache.camel.ExtendedCamelContext; +import org.apache.camel.NoFactoryAvailableException; +import org.apache.camel.console.DevConsole; +import org.apache.camel.console.DevConsoleResolver; +import org.apache.camel.spi.FactoryFinder; + +/** + * 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 static final String DEV_CONSOLE_RESOURCE_PATH = "META-INF/services/org/apache/camel/dev-console/"; + + protected FactoryFinder devConsoleFactory; + private CamelContext camelContext; + + @Override + public CamelContext getCamelContext() { + return camelContext; + } + + @Override + public void setCamelContext(CamelContext camelContext) { + this.camelContext = camelContext; + } + + @Override + public DevConsole resolveDevConsole(String id) { + // lookup in registry first + DevConsole answer = camelContext.getRegistry().lookupByNameAndType(id + "-dev-console", DevConsole.class); + if (answer == null) { + answer = camelContext.getRegistry().lookupByNameAndType(id, DevConsole.class); + } + if (answer != null) { + return answer; + } + + Class<?> type = null; + try { + type = findDevConsole(id, camelContext); + } catch (NoFactoryAvailableException e) { + // ignore + } catch (Exception e) { + throw new IllegalArgumentException("Invalid URI, no DevConsole registered for id: " + id, e); + } + + if (type != null) { + if (DevConsole.class.isAssignableFrom(type)) { + return (DevConsole) camelContext.getInjector().newInstance(type, false); + } else { + throw new IllegalArgumentException( + "Resolving dev-console: " + id + " detected type conflict: Not a DevConsole implementation. Found: " + + type.getName()); + } + } + + return null; + } + + protected Class<?> findDevConsole(String name, CamelContext context) throws Exception { + if (devConsoleFactory == null) { + devConsoleFactory = context.adapt(ExtendedCamelContext.class).getFactoryFinder(DEV_CONSOLE_RESOURCE_PATH); + } + return devConsoleFactory.findOptionalClass(name).orElse(null); + } + +} 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 8d02c26..d3a7ab1 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 @@ -26,6 +26,7 @@ import org.apache.camel.Route; import org.apache.camel.RouteTemplateContext; import org.apache.camel.TypeConverter; import org.apache.camel.catalog.RuntimeCamelCatalog; +import org.apache.camel.console.DevConsoleResolver; import org.apache.camel.health.HealthCheckRegistry; import org.apache.camel.health.HealthCheckResolver; import org.apache.camel.impl.converter.DefaultTypeConverter; @@ -283,6 +284,11 @@ public class SimpleCamelContext extends AbstractCamelContext { } @Override + protected DevConsoleResolver createDevConsoleResolver() { + return new DefaultDevConsoleResolver(); + } + + @Override protected MessageHistoryFactory createMessageHistoryFactory() { return new DefaultMessageHistoryFactory(); } 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 54bc4a1..0df43cb 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 @@ -61,6 +61,8 @@ public class ExtendedCamelContextConfigurer extends org.apache.camel.support.com case "DeferServiceFactory": target.setDeferServiceFactory(property(camelContext, org.apache.camel.spi.DeferServiceFactory.class, value)); return true; case "delayer": case "Delayer": target.setDelayer(property(camelContext, java.lang.Long.class, value)); return true; + case "devconsoleresolver": + case "DevConsoleResolver": target.setDevConsoleResolver(property(camelContext, org.apache.camel.console.DevConsoleResolver.class, value)); return true; case "dumproutes": case "DumpRoutes": target.setDumpRoutes(property(camelContext, java.lang.Boolean.class, value)); return true; case "errorhandlerfactory": @@ -244,6 +246,8 @@ public class ExtendedCamelContextConfigurer extends org.apache.camel.support.com case "DeferServiceFactory": return org.apache.camel.spi.DeferServiceFactory.class; case "delayer": case "Delayer": return java.lang.Long.class; + case "devconsoleresolver": + case "DevConsoleResolver": return org.apache.camel.console.DevConsoleResolver.class; case "dumproutes": case "DumpRoutes": return java.lang.Boolean.class; case "errorhandlerfactory": @@ -428,6 +432,8 @@ public class ExtendedCamelContextConfigurer extends org.apache.camel.support.com case "DeferServiceFactory": return target.getDeferServiceFactory(); case "delayer": case "Delayer": return target.getDelayer(); + case "devconsoleresolver": + case "DevConsoleResolver": return target.getDevConsoleResolver(); case "dumproutes": case "DumpRoutes": return target.isDumpRoutes(); case "errorhandlerfactory": 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 8fc20d9..ecc68de 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 @@ -54,6 +54,7 @@ import org.apache.camel.TypeConverter; import org.apache.camel.ValueHolder; import org.apache.camel.builder.AdviceWithRouteBuilder; import org.apache.camel.catalog.RuntimeCamelCatalog; +import org.apache.camel.console.DevConsoleResolver; import org.apache.camel.health.HealthCheckResolver; import org.apache.camel.impl.DefaultCamelContext; import org.apache.camel.model.DataFormatDefinition; @@ -1293,6 +1294,16 @@ public class LightweightCamelContext implements ExtendedCamelContext, CatalogCam } @Override + public DevConsoleResolver getDevConsoleResolver() { + return getExtendedCamelContext().getDevConsoleResolver(); + } + + @Override + public void setDevConsoleResolver(DevConsoleResolver devConsoleResolver) { + getExtendedCamelContext().setDevConsoleResolver(devConsoleResolver); + } + + @Override public PackageScanClassResolver getPackageScanClassResolver() { return getExtendedCamelContext().getPackageScanClassResolver(); } 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 55d7836..0601169 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 @@ -62,6 +62,7 @@ import org.apache.camel.StartupSummaryLevel; import org.apache.camel.TypeConverter; import org.apache.camel.ValueHolder; import org.apache.camel.catalog.RuntimeCamelCatalog; +import org.apache.camel.console.DevConsoleResolver; import org.apache.camel.health.HealthCheckResolver; import org.apache.camel.impl.converter.CoreTypeConverterRegistry; import org.apache.camel.impl.engine.DefaultComponentResolver; @@ -167,6 +168,7 @@ public class LightweightRuntimeCamelContext implements ExtendedCamelContext, Cat private final LanguageResolver languageResolver; private final DataFormatResolver dataFormatResolver; private final HealthCheckResolver healthCheckResolver; + private final DevConsoleResolver devConsoleResolver; private final UuidGenerator uuidGenerator; private final EndpointRegistry<? extends ValueHolder<String>> endpoints; private final Map<String, Component> components; @@ -217,6 +219,7 @@ public class LightweightRuntimeCamelContext implements ExtendedCamelContext, Cat languageResolver = context.adapt(ExtendedCamelContext.class).getLanguageResolver(); dataFormatResolver = context.adapt(ExtendedCamelContext.class).getDataFormatResolver(); healthCheckResolver = context.adapt(ExtendedCamelContext.class).getHealthCheckResolver(); + devConsoleResolver = context.adapt(ExtendedCamelContext.class).getDevConsoleResolver(); endpoints = context.getEndpointRegistry(); components = context.getComponentNames().stream().collect(Collectors.toMap(s -> s, context::hasComponent)); languages = context.getLanguageNames().stream().collect(Collectors.toMap(s -> s, context::resolveLanguage)); @@ -571,6 +574,16 @@ public class LightweightRuntimeCamelContext implements ExtendedCamelContext, Cat } @Override + public DevConsoleResolver getDevConsoleResolver() { + return devConsoleResolver; + } + + @Override + public void setDevConsoleResolver(DevConsoleResolver devConsoleResolver) { + throw new UnsupportedOperationException(); + } + + @Override public UuidGenerator getUuidGenerator() { return uuidGenerator; }