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 2021/12/30 12:04:22 UTC

[camel] 06/30: CAMEL-17384: Developer Console SPI

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 <cl...@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;
     }