You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by or...@apache.org on 2023/03/29 10:00:17 UTC
[camel] 01/03: CAMEL-15105: created a plugin manager to manage extensions to the context
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
commit e0376969239d08d9cf9c14022f5393a0766fcbc4
Author: Otavio Rodolfo Piske <an...@gmail.com>
AuthorDate: Thu Mar 23 11:45:05 2023 +0100
CAMEL-15105: created a plugin manager to manage extensions to the context
---
.../org/apache/camel/ExtendedCamelContext.java | 23 ++++++++
.../java/org/apache/camel/spi/PluginManager.java | 36 +++++++++++++
.../camel/impl/engine/AbstractCamelContext.java | 37 +++----------
.../impl/engine/DefaultCamelContextExtension.java | 27 ++++++++++
.../impl/engine/DefaultContextPluginManager.java | 63 ++++++++++++++++++++++
.../impl/lw/LightweightCamelContextExtension.java | 16 ++++++
6 files changed, 172 insertions(+), 30 deletions(-)
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 6566b09778a..641a0bac7fc 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
@@ -61,6 +61,7 @@ import org.apache.camel.spi.PackageScanClassResolver;
import org.apache.camel.spi.PackageScanResourceResolver;
import org.apache.camel.spi.PeriodTaskResolver;
import org.apache.camel.spi.PeriodTaskScheduler;
+import org.apache.camel.spi.PluginManager;
import org.apache.camel.spi.ProcessorExchangeFactory;
import org.apache.camel.spi.ProcessorFactory;
import org.apache.camel.spi.ReactiveExecutor;
@@ -910,4 +911,26 @@ public interface ExtendedCamelContext {
*/
void setPeriodTaskResolver(PeriodTaskResolver periodTaskResolver);
+ /**
+ * Gets access to the internal plugin manager
+ * @return the internal plugin manager
+ */
+ @Deprecated
+ PluginManager getPluginManager();
+
+ /**
+ * Gets a plugin of the given type.
+ *
+ * @param type the type of the extension
+ * @return the extension, or <tt>null</tt> if no extension has been installed.
+ */
+ <T> T getContextPlugin(Class<T> type);
+
+ /**
+ * Allows installation of custom plugins to the Camel context.
+ *
+ * @param type the type of the extension
+ * @param module the instance of the extension
+ */
+ <T> void addContextPlugin(Class<T> type, T module);
}
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/PluginManager.java b/core/camel-api/src/main/java/org/apache/camel/spi/PluginManager.java
new file mode 100644
index 00000000000..504ca54ab75
--- /dev/null
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/PluginManager.java
@@ -0,0 +1,36 @@
+/*
+ * 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.spi;
+
+public interface PluginManager {
+ /**
+ * Gets a plugin of the given type.
+ *
+ * @param type the type of the extension
+ * @return the extension, or <tt>null</tt> if no extension has been installed.
+ */
+ <T> T getContextPlugin(Class<T> type);
+
+ /**
+ * Allows installation of custom plugins to the Camel context.
+ *
+ * @param type the type of the extension
+ * @param module the instance of the extension
+ */
+ <T> void addContextPlugin(Class<T> type, T module);
+}
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 17e696579a7..fbd1ec9333e 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
@@ -40,6 +40,7 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
import java.util.function.Supplier;
import org.apache.camel.CamelContext;
@@ -133,6 +134,7 @@ import org.apache.camel.spi.PackageScanClassResolver;
import org.apache.camel.spi.PackageScanResourceResolver;
import org.apache.camel.spi.PeriodTaskResolver;
import org.apache.camel.spi.PeriodTaskScheduler;
+import org.apache.camel.spi.PluginManager;
import org.apache.camel.spi.ProcessorExchangeFactory;
import org.apache.camel.spi.ProcessorFactory;
import org.apache.camel.spi.PropertiesComponent;
@@ -271,8 +273,8 @@ public abstract class AbstractCamelContext extends BaseService
private final InternalRouteStartupManager internalRouteStartupManager = new InternalRouteStartupManager(this);
private final List<RouteStartupOrder> routeStartupOrder = new ArrayList<>();
private final StopWatch stopWatch = new StopWatch(false);
- private final Map<Class<?>, Object> extensions = new ConcurrentHashMap<>();
- private final ThreadLocal<Set<String>> componentsInCreation = ThreadLocal.withInitial(HashSet::new);
+ private final PluginManager pluginManager;
+ private final ThreadLocal<Set<String>> componentsInCreation = ThreadLocal.withInitial(() -> new HashSet<>());
private VetoCamelContextStartException vetoed;
private String managementName;
private ClassLoader applicationContextClassLoader;
@@ -387,6 +389,7 @@ public abstract class AbstractCamelContext extends BaseService
this.bootstraps.add(bootstrapFactories::clear);
this.internalServiceManager = new InternalServiceManager(this, internalRouteStartupManager, startupListeners);
+ this.pluginManager = new DefaultContextPluginManager(internalServiceManager);
if (build) {
try {
@@ -444,38 +447,12 @@ public abstract class AbstractCamelContext extends BaseService
return type.cast(this);
}
- // lookup by direct implementatiin
- Object extension = extensions.get(type);
- if (extension == null) {
- // fallback and lookup via interfaces
- for (Object e : extensions.values()) {
- if (type.isInstance(e)) {
- return type.cast(e);
- }
- }
- }
- if (extension instanceof Supplier) {
- extension = ((Supplier) extension).get();
- setExtension(type, (T) extension);
- }
- return (T) extension;
+ return pluginManager.getContextPlugin(type);
}
@Override
public <T> void setExtension(Class<T> type, T module) {
- if (module != null) {
- try {
- extensions.put(type, internalServiceManager.addService(module));
- } catch (Exception e) {
- throw RuntimeCamelException.wrapRuntimeCamelException(e);
- }
- }
- }
-
- public <T> void setDefaultExtension(Class<T> type, Supplier<T> module) {
- if (module != null) {
- extensions.putIfAbsent(type, module);
- }
+ pluginManager.addContextPlugin(type, module);
}
@Override
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelContextExtension.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelContextExtension.java
index 2e739885ad3..4aeaa519cd0 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelContextExtension.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelContextExtension.java
@@ -80,6 +80,7 @@ import org.apache.camel.spi.PackageScanClassResolver;
import org.apache.camel.spi.PackageScanResourceResolver;
import org.apache.camel.spi.PeriodTaskResolver;
import org.apache.camel.spi.PeriodTaskScheduler;
+import org.apache.camel.spi.PluginManager;
import org.apache.camel.spi.ProcessorExchangeFactory;
import org.apache.camel.spi.ProcessorFactory;
import org.apache.camel.spi.PropertiesComponent;
@@ -108,6 +109,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
private final List<InterceptStrategy> interceptStrategies = new ArrayList<>();
private final Map<String, FactoryFinder> factories = new ConcurrentHashMap<>();
private final Set<LogListener> logListeners = new LinkedHashSet<>();
+ private final PluginManager pluginManager = new DefaultContextPluginManager();
private volatile String description;
@Deprecated
private ErrorHandlerFactory errorHandlerFactory;
@@ -1150,4 +1152,29 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
public String getTestExcludeRoutes() {
return camelContext.getTestExcludeRoutes();
}
+
+ @Override
+ public PluginManager getPluginManager() {
+ return pluginManager;
+ }
+
+ @Override
+ public <T> T getContextPlugin(Class<T> type) {
+ T ret = pluginManager.getContextPlugin(type);
+
+ // Note: this is because of interfaces like Model which are still tightly coupled with the context
+ if (ret == null) {
+ if (type.isInstance(camelContext)) {
+ return type.cast(camelContext);
+ }
+ }
+
+ return ret;
+ }
+
+ @Override
+ public <T> void addContextPlugin(Class<T> type, T module) {
+ final T addedModule = camelContext.getInternalServiceManager().addService(module);
+ pluginManager.addContextPlugin(type, addedModule);
+ }
}
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultContextPluginManager.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultContextPluginManager.java
new file mode 100644
index 00000000000..090078ba97d
--- /dev/null
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultContextPluginManager.java
@@ -0,0 +1,63 @@
+/*
+ * 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 java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Supplier;
+
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.spi.PluginManager;
+
+public class DefaultContextPluginManager implements PluginManager {
+ private final Map<Class<?>, Object> extensions = new ConcurrentHashMap<>();
+
+ public DefaultContextPluginManager() {
+
+ }
+
+ @Override
+ public <T> T getContextPlugin(Class<T> type) {
+ // lookup by direct implementation
+ Object extension = extensions.get(type);
+ if (extension == null) {
+ // fallback and lookup via interfaces
+ for (Object e : extensions.values()) {
+ if (type.isInstance(e)) {
+ return type.cast(e);
+ }
+ }
+ }
+ if (extension instanceof Supplier) {
+ extension = ((Supplier) extension).get();
+ addContextPlugin(type, (T) extension);
+ }
+ return (T) extension;
+ }
+
+ @Override
+ public <T> void addContextPlugin(Class<T> type, T module) {
+ if (module != null) {
+ try {
+ extensions.put(type, module);
+ } catch (Exception e) {
+ throw RuntimeCamelException.wrapRuntimeCamelException(e);
+ }
+ }
+ }
+}
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContextExtension.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContextExtension.java
index 25ed86d82da..6125fdd7fef 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContextExtension.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContextExtension.java
@@ -75,6 +75,7 @@ import org.apache.camel.spi.PackageScanClassResolver;
import org.apache.camel.spi.PackageScanResourceResolver;
import org.apache.camel.spi.PeriodTaskResolver;
import org.apache.camel.spi.PeriodTaskScheduler;
+import org.apache.camel.spi.PluginManager;
import org.apache.camel.spi.ProcessorExchangeFactory;
import org.apache.camel.spi.ProcessorFactory;
import org.apache.camel.spi.PropertiesComponent;
@@ -893,6 +894,21 @@ class LightweightCamelContextExtension implements ExtendedCamelContext {
throw new UnsupportedOperationException();
}
+ @Override
+ public PluginManager getPluginManager() {
+ return camelContext.getCamelContextExtension().getPluginManager();
+ }
+
+ @Override
+ public <T> T getContextPlugin(Class<T> type) {
+ return camelContext.getCamelContextExtension().getPluginManager().getContextPlugin(type);
+ }
+
+ @Override
+ public <T> void addContextPlugin(Class<T> type, T module) {
+ camelContext.getCamelContextExtension().addContextPlugin(type, module);
+ }
+
Endpoint doGetEndpoint(String uri, boolean normalized, boolean prototype) {
StringHelper.notEmpty(uri, "uri");
// in case path has property placeholders then try to let property