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 2022/12/18 11:34:12 UTC
[camel] 03/03: CAMEL-18815: camel-jbang - Base package scan to search in downloaded JARs
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
commit 343319ff302eed55894c85cb16888553795c698a
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Sun Dec 18 12:32:29 2022 +0100
CAMEL-18815: camel-jbang - Base package scan to search in downloaded JARs
---
.../org/apache/camel/main/BaseMainSupport.java | 10 +-
.../java/org/apache/camel/main/KameletMain.java | 2 +
.../download/BasePackageScanDownloadListener.java | 105 +++++++++++++++++++++
3 files changed, 114 insertions(+), 3 deletions(-)
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
index e5d6aa38f0a..6d1fe5e36de 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
@@ -491,6 +491,8 @@ public abstract class BaseMainSupport extends BaseService {
// configure from main configuration properties
doConfigureCamelContextFromMainConfiguration(camelContext, mainConfigurationProperties, autoConfiguredProperties);
+ configurePackageScan(camelContext);
+
// try to load configuration classes
loadConfigurations(camelContext);
@@ -594,9 +596,11 @@ public abstract class BaseMainSupport extends BaseService {
protected void configurePackageScan(CamelContext camelContext) {
if (mainConfigurationProperties.isBasePackageScanEnabled()) {
// only set the base package if enabled
- camelContext.adapt(ExtendedCamelContext.class).setBasePackageScan(mainConfigurationProperties.getBasePackageScan());
- if (mainConfigurationProperties.getBasePackageScan() != null) {
- LOG.info("Classpath scanning enabled from base package: {}", mainConfigurationProperties.getBasePackageScan());
+ String base = mainConfigurationProperties.getBasePackageScan();
+ String current = camelContext.adapt(ExtendedCamelContext.class).getBasePackageScan();
+ if (base != null && !base.equals(current)) {
+ camelContext.adapt(ExtendedCamelContext.class).setBasePackageScan(base);
+ LOG.info("Classpath scanning enabled from base package: {}", base);
}
}
}
diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
index 9c31b64fba1..df29d50d8fb 100644
--- a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
+++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
@@ -27,6 +27,7 @@ import org.apache.camel.ProducerTemplate;
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.main.download.AutoConfigureDownloadListener;
+import org.apache.camel.main.download.BasePackageScanDownloadListener;
import org.apache.camel.main.download.CircuitBreakerDownloader;
import org.apache.camel.main.download.CommandLineDependencyDownloader;
import org.apache.camel.main.download.DependencyDownloaderClassLoader;
@@ -320,6 +321,7 @@ public class KameletMain extends MainCommandLineSupport {
}
downloader.addDownloadListener(new AutoConfigureDownloadListener());
downloader.addArtifactDownloadListener(new TypeConverterLoaderDownloadListener());
+ downloader.addArtifactDownloadListener(new BasePackageScanDownloadListener());
// register as extension
try {
diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/BasePackageScanDownloadListener.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/BasePackageScanDownloadListener.java
new file mode 100644
index 00000000000..cbb4e121f85
--- /dev/null
+++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/BasePackageScanDownloadListener.java
@@ -0,0 +1,105 @@
+/*
+ * 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.main.download;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.camel.CamelConfiguration;
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.Configuration;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.spi.CamelBeanPostProcessor;
+import org.apache.camel.spi.PackageScanClassResolver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BasePackageScanDownloadListener implements ArtifactDownloadListener, CamelContextAware {
+
+ private static final Logger LOG = LoggerFactory.getLogger(BasePackageScanDownloadListener.class);
+
+ private CamelContext camelContext;
+
+ private final Set<String> scanned = new HashSet<>();
+
+ @Override
+ public CamelContext getCamelContext() {
+ return camelContext;
+ }
+
+ @Override
+ public void setCamelContext(CamelContext camelContext) {
+ this.camelContext = camelContext;
+ }
+
+ @Override
+ public void onDownloadedFile(File file) {
+ String basePackage = camelContext.adapt(ExtendedCamelContext.class).getBasePackageScan();
+ if (basePackage != null) {
+ try {
+ basePackageScanConfiguration(basePackage, file);
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+
+ protected void basePackageScanConfiguration(String basePackage, File file) throws Exception {
+ Collection<CamelConfiguration> configs = new ArrayList<>();
+ // we only want to scan via isolated classloader
+ PackageScanClassResolver pscr = camelContext.adapt(ExtendedCamelContext.class).getPackageScanClassResolver();
+ Set<Class<?>> found1 = pscr.findImplementations(CamelConfiguration.class, basePackage);
+ Set<Class<?>> found2 = pscr.findAnnotated(Configuration.class, basePackage);
+ Set<Class<?>> found = new LinkedHashSet<>();
+ found.addAll(found1);
+ found.addAll(found2);
+ for (Class<?> clazz : found) {
+ // avoid duplicate if we scan other JARs that can same class from previous downloads
+ String fqn = clazz.getName();
+ if (scanned.contains(fqn)) {
+ continue;
+ } else {
+ scanned.add(fqn);
+ }
+
+ // lets use Camel's injector so the class has some support for dependency injection
+ Object config = camelContext.getInjector().newInstance(clazz);
+ if (config instanceof CamelConfiguration) {
+ LOG.debug("Discovered CamelConfiguration class: {}", clazz);
+ CamelConfiguration cc = (CamelConfiguration) config;
+ configs.add(cc);
+ }
+ }
+
+ CamelBeanPostProcessor postProcessor = camelContext.adapt(ExtendedCamelContext.class).getBeanPostProcessor();
+ // prepare the directly configured instances
+ for (Object configuration : configs) {
+ postProcessor.postProcessBeforeInitialization(configuration, configuration.getClass().getName());
+ postProcessor.postProcessAfterInitialization(configuration, configuration.getClass().getName());
+ }
+ // invoke configure on configurations
+ for (CamelConfiguration config : configs) {
+ config.configure(camelContext);
+ }
+ }
+
+}