This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch ff in repository https://gitbox.apache.org/repos/asf/camel.git
commit 96049f574a155aee22b9f444fc06dec3f0c992a0 Author: Claus Ibsen <[email protected]> AuthorDate: Fri Feb 27 22:08:35 2026 +0100 CAMEL-23102: camel-jbang - Automatic keep up to date list of Camel FactoryFinder as known dependencies --- components/camel-oauth/src/main/docs/oauth.adoc | 5 +- .../apache/camel/openapi/RestOpenApiSupport.java | 7 +- .../platform/http/main/MainHttpServer.java | 8 +- .../platform/http/main/ManagementHttpServer.java | 8 +- .../apache/camel/spring/SpringCamelContext.java | 14 +- .../org/apache/camel/NoSuchServiceException.java | 40 +++++ .../camel/impl/engine/SimpleCamelContext.java | 182 ++++++--------------- .../simple/ast/SimpleFunctionExpression.java | 49 ++---- .../java/org/apache/camel/support/OAuthHelper.java | 9 +- .../org/apache/camel/support/ResolverHelper.java | 60 ++++++- ...mel-factoryfinder-known-dependencies.properties | 64 ++++++++ .../java/org/apache/camel/main/KameletMain.java | 7 + .../download/DependencyDownloadFactoryFinder.java | 55 +++++++ .../DependencyDownloadFactoryFinderResolver.java | 44 +++++ .../main/download/KnownDependenciesResolver.java | 4 + .../camel-main-known-dependencies.properties | 50 +++--- .../maven/packaging/PrepareKameletMainMojo.java | 72 ++++++++ 17 files changed, 450 insertions(+), 228 deletions(-) diff --git a/components/camel-oauth/src/main/docs/oauth.adoc b/components/camel-oauth/src/main/docs/oauth.adoc index 08b9717e10c2..c16651fd7d01 100644 --- a/components/camel-oauth/src/main/docs/oauth.adoc +++ b/components/camel-oauth/src/main/docs/oauth.adoc @@ -162,10 +162,9 @@ import org.apache.camel.spi.OAuthClientAuthenticationFactory; import org.apache.camel.spi.OAuthClientConfig; import org.apache.camel.support.ResolverHelper; -OAuthClientAuthenticationFactory factory = ResolverHelper.resolveService( +OAuthClientAuthenticationFactory factory = ResolverHelper.resolveMandatoryService( context, OAuthClientAuthenticationFactory.FACTORY, - OAuthClientAuthenticationFactory.class) - .orElseThrow(() -> new IllegalArgumentException("Add camel-oauth to the classpath")); + OAuthClientAuthenticationFactory.class, "camel-oauth"); String token = factory.resolveToken( new OAuthClientConfig() diff --git a/components/camel-openapi-java/src/main/java/org/apache/camel/openapi/RestOpenApiSupport.java b/components/camel-openapi-java/src/main/java/org/apache/camel/openapi/RestOpenApiSupport.java index 7920dff28891..d4b0de1c21d5 100644 --- a/components/camel-openapi-java/src/main/java/org/apache/camel/openapi/RestOpenApiSupport.java +++ b/components/camel-openapi-java/src/main/java/org/apache/camel/openapi/RestOpenApiSupport.java @@ -300,13 +300,12 @@ public class RestOpenApiSupport { } protected RestDefinitionsResolver createJmxRestDefinitionsResolver(CamelContext camelContext) { - return ResolverHelper.resolveService( + return ResolverHelper.resolveMandatoryService( camelContext, camelContext.getCamelContextExtension().getBootstrapFactoryFinder(), JMX_REST_DEFINITION_RESOLVER, - RestDefinitionsResolver.class) - .orElseThrow( - () -> new IllegalArgumentException("Cannot find camel-openapi-java on classpath.")); + RestDefinitionsResolver.class, + "camel-openapi-java"); } public void setupXForwardHeaders(RestApiResponseAdapter response, Exchange exchange) { diff --git a/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServer.java b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServer.java index 125913eae0a9..4881996cc03d 100644 --- a/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServer.java +++ b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServer.java @@ -19,7 +19,6 @@ package org.apache.camel.component.platform.http.main; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; -import java.util.Optional; import io.vertx.core.Handler; import io.vertx.core.http.impl.MimeMapping; @@ -304,12 +303,11 @@ public class MainHttpServer extends ServiceSupport implements CamelContextAware, } protected PlatformHttpPluginRegistry resolvePlatformHttpPluginRegistry() { - Optional<PlatformHttpPluginRegistry> result = ResolverHelper.resolveService( + return ResolverHelper.resolveMandatoryService( getCamelContext(), PlatformHttpPluginRegistry.FACTORY, - PlatformHttpPluginRegistry.class); - return result.orElseThrow(() -> new IllegalArgumentException( - "Cannot create PlatformHttpPluginRegistry. Make sure camel-platform-http JAR is on classpath.")); + PlatformHttpPluginRegistry.class, + "camel-platform-http"); } protected void setupStartupSummary() throws Exception { diff --git a/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/ManagementHttpServer.java b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/ManagementHttpServer.java index 376fd86a3b55..6ec3285eb3ca 100644 --- a/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/ManagementHttpServer.java +++ b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/ManagementHttpServer.java @@ -29,7 +29,6 @@ import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.Set; import java.util.StringJoiner; import java.util.TreeSet; @@ -895,12 +894,11 @@ public class ManagementHttpServer extends ServiceSupport implements CamelContext } protected PlatformHttpPluginRegistry resolvePlatformHttpPluginRegistry() { - Optional<PlatformHttpPluginRegistry> result = ResolverHelper.resolveService( + return ResolverHelper.resolveMandatoryService( getCamelContext(), PlatformHttpPluginRegistry.FACTORY, - PlatformHttpPluginRegistry.class); - return result.orElseThrow(() -> new IllegalArgumentException( - "Cannot create PlatformHttpPluginRegistry. Make sure camel-platform-http JAR is on classpath.")); + PlatformHttpPluginRegistry.class, + "camel-platform-http"); } private static void healthCheckStatus(JsonObject jo, boolean up) { diff --git a/components/camel-spring-parent/camel-spring/src/main/java/org/apache/camel/spring/SpringCamelContext.java b/components/camel-spring-parent/camel-spring/src/main/java/org/apache/camel/spring/SpringCamelContext.java index 94fb745b45ea..ee490b001bb5 100644 --- a/components/camel-spring-parent/camel-spring/src/main/java/org/apache/camel/spring/SpringCamelContext.java +++ b/components/camel-spring-parent/camel-spring/src/main/java/org/apache/camel/spring/SpringCamelContext.java @@ -16,8 +16,6 @@ */ package org.apache.camel.spring; -import java.util.Optional; - import org.apache.camel.Endpoint; import org.apache.camel.Processor; import org.apache.camel.RuntimeCamelException; @@ -258,18 +256,12 @@ public class SpringCamelContext extends DefaultCamelContext @Override protected ModelJAXBContextFactory createModelJAXBContextFactory() { - Optional<ModelJAXBContextFactory> result = ResolverHelper.resolveService( + return ResolverHelper.resolveMandatoryService( getCamelContextReference(), getCamelContextExtension().getBootstrapFactoryFinder(), ModelJAXBContextFactory.FACTORY + "-spring", - ModelJAXBContextFactory.class); - - if (result.isPresent()) { - return result.get(); - } else { - throw new IllegalArgumentException( - "Cannot find ModelJAXBContextFactory on classpath. Add camel-spring-xml to classpath."); - } + ModelJAXBContextFactory.class, + "camel-spring-xml"); } @Override diff --git a/core/camel-api/src/main/java/org/apache/camel/NoSuchServiceException.java b/core/camel-api/src/main/java/org/apache/camel/NoSuchServiceException.java new file mode 100644 index 000000000000..9d6cd80a4d95 --- /dev/null +++ b/core/camel-api/src/main/java/org/apache/camel/NoSuchServiceException.java @@ -0,0 +1,40 @@ +/* + * 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; + +/** + * A runtime exception if a given service could not be found in the classpath + */ +public class NoSuchServiceException extends RuntimeCamelException { + + private final String name; + private final String jar; + + public NoSuchServiceException(String name, String jar) { + super("No " + name + " service could be found in the classpath. Add " + jar + " to classpath."); + this.name = name; + this.jar = jar; + } + + public String getName() { + return name; + } + + public String getJar() { + return jar; + } +} 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 cd5884d4ccd1..74f27ad17234 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 @@ -247,18 +247,12 @@ public class SimpleCamelContext extends AbstractCamelContext { @Override protected ModelJAXBContextFactory createModelJAXBContextFactory() { - Optional<ModelJAXBContextFactory> result = ResolverHelper.resolveService( + return ResolverHelper.resolveMandatoryService( getCamelContextReference(), getCamelContextExtension().getBootstrapFactoryFinder(), ModelJAXBContextFactory.FACTORY, - ModelJAXBContextFactory.class); - - if (result.isPresent()) { - return result.get(); - } else { - throw new IllegalArgumentException( - "Cannot find ModelJAXBContextFactory on classpath. Add camel-xml-jaxb to classpath."); - } + ModelJAXBContextFactory.class, + "camel-xml-jaxb"); } @Override @@ -303,34 +297,21 @@ public class SimpleCamelContext extends AbstractCamelContext { @Override protected ProcessorFactory createProcessorFactory() { - Optional<ProcessorFactory> result = ResolverHelper.resolveService( + return ResolverHelper.resolveMandatoryService( getCamelContextReference(), getCamelContextExtension().getBootstrapFactoryFinder(), ProcessorFactory.FACTORY, - ProcessorFactory.class); - - if (result.isPresent()) { - return result.get(); - } else { - throw new IllegalArgumentException( - "Cannot find ProcessorFactory on classpath. Add camel-core-processor to classpath."); - } + ProcessorFactory.class, "camel-core-processor"); } @Override protected InternalProcessorFactory createInternalProcessorFactory() { - Optional<InternalProcessorFactory> result = ResolverHelper.resolveService( + return ResolverHelper.resolveMandatoryService( getCamelContextReference(), getCamelContextExtension().getBootstrapFactoryFinder(), InternalProcessorFactory.FACTORY, - InternalProcessorFactory.class); - - if (result.isPresent()) { - return result.get(); - } else { - throw new IllegalArgumentException( - "Cannot find InternalProcessorFactory on classpath. Add camel-core-processor to classpath."); - } + InternalProcessorFactory.class, + "camel-core-processor"); } @Override @@ -409,18 +390,12 @@ public class SimpleCamelContext extends AbstractCamelContext { @Override protected RuntimeCamelCatalog createRuntimeCamelCatalog() { - Optional<RuntimeCamelCatalog> result = ResolverHelper.resolveService( + return ResolverHelper.resolveMandatoryService( getCamelContextReference(), getCamelContextExtension().getBootstrapFactoryFinder(), RuntimeCamelCatalog.FACTORY, - RuntimeCamelCatalog.class); - - if (result.isPresent()) { - return result.get(); - } else { - throw new IllegalArgumentException( - "Cannot find RuntimeCamelCatalog on classpath. Add camel-core-catalog to classpath."); - } + RuntimeCamelCatalog.class, + "camel-core-catalog"); } @Override @@ -437,21 +412,17 @@ public class SimpleCamelContext extends AbstractCamelContext { DumpRoutesStrategy.FACTORY, DumpRoutesStrategy.class); - if (result.isEmpty()) { - // lookup default factory - result = ResolverHelper.resolveService( - getCamelContextReference(), - getCamelContextExtension().getBootstrapFactoryFinder(), - "default-" + DumpRoutesStrategy.FACTORY, - DumpRoutesStrategy.class); - } - if (result.isPresent()) { return result.get(); - } else { - throw new IllegalArgumentException( - "Cannot find DumpRoutesStrategy on classpath. Add camel-core-engine to classpath."); } + + // lookup default factory + return ResolverHelper.resolveMandatoryService( + getCamelContextReference(), + getCamelContextExtension().getBootstrapFactoryFinder(), + "default-" + DumpRoutesStrategy.FACTORY, + DumpRoutesStrategy.class, + "camel-core-engine"); } @Override @@ -509,64 +480,42 @@ public class SimpleCamelContext extends AbstractCamelContext { @Override protected BeanProxyFactory createBeanProxyFactory() { - Optional<BeanProxyFactory> result = ResolverHelper.resolveService( + return ResolverHelper.resolveMandatoryService( getCamelContextReference(), getCamelContextExtension().getBootstrapFactoryFinder(), BeanProxyFactory.FACTORY, - BeanProxyFactory.class); - - if (result.isPresent()) { - return result.get(); - } else { - throw new IllegalArgumentException("Cannot find BeanProxyFactory on classpath. Add camel-bean to classpath."); - } + BeanProxyFactory.class, + "camel-bean"); } @Override protected AnnotationBasedProcessorFactory createAnnotationBasedProcessorFactory() { - Optional<AnnotationBasedProcessorFactory> result = ResolverHelper.resolveService( + return ResolverHelper.resolveMandatoryService( getCamelContextReference(), getCamelContextExtension().getBootstrapFactoryFinder(), AnnotationBasedProcessorFactory.FACTORY, - AnnotationBasedProcessorFactory.class); - - if (result.isPresent()) { - return result.get(); - } else { - throw new IllegalArgumentException( - "Cannot find AnnotationBasedProcessorFactory on classpath. Add camel-core-processor to classpath."); - } + AnnotationBasedProcessorFactory.class, + "camel-core-processor"); } @Override protected DeferServiceFactory createDeferServiceFactory() { - Optional<DeferServiceFactory> result = ResolverHelper.resolveService( + return ResolverHelper.resolveMandatoryService( getCamelContextReference(), getCamelContextExtension().getBootstrapFactoryFinder(), DeferServiceFactory.FACTORY, - DeferServiceFactory.class); - - if (result.isPresent()) { - return result.get(); - } else { - throw new IllegalArgumentException( - "Cannot find DeferServiceFactory on classpath. Add camel-core-processor to classpath."); - } + DeferServiceFactory.class, + "camel-core-processor"); } @Override protected BeanProcessorFactory createBeanProcessorFactory() { - Optional<BeanProcessorFactory> result = ResolverHelper.resolveService( + return ResolverHelper.resolveMandatoryService( getCamelContextReference(), getCamelContextExtension().getBootstrapFactoryFinder(), BeanProcessorFactory.FACTORY, - BeanProcessorFactory.class); - - if (result.isPresent()) { - return result.get(); - } else { - throw new IllegalArgumentException("Cannot find BeanProcessorFactory on classpath. Add camel-bean to classpath."); - } + BeanProcessorFactory.class, + "camel-bean"); } @Override @@ -598,80 +547,52 @@ public class SimpleCamelContext extends AbstractCamelContext { @Override protected ModelToXMLDumper createModelToXMLDumper() { - Optional<ModelToXMLDumper> result = ResolverHelper.resolveService( + return ResolverHelper.resolveMandatoryService( getCamelContextReference(), getCamelContextExtension().getBootstrapFactoryFinder(), ModelToXMLDumper.FACTORY, - ModelToXMLDumper.class); - - if (result.isPresent()) { - return result.get(); - } else { - throw new IllegalArgumentException("Cannot find ModelToXMLDumper on classpath. Add camel-xml-io to classpath."); - } + ModelToXMLDumper.class, + "camel-xml-io"); } @Override protected ModelToYAMLDumper createModelToYAMLDumper() { - Optional<ModelToYAMLDumper> result = ResolverHelper.resolveService( + return ResolverHelper.resolveMandatoryService( getCamelContextReference(), getCamelContextExtension().getBootstrapFactoryFinder(), ModelToYAMLDumper.FACTORY, - ModelToYAMLDumper.class); - - if (result.isPresent()) { - return result.get(); - } else { - throw new IllegalArgumentException("Cannot find ModelToYAMLDumper on classpath. Add camel-yaml-io to classpath."); - } + ModelToYAMLDumper.class, + "camel-yaml-io"); } @Override protected ModelToStructureDumper createModelToStructureDumper() { - Optional<ModelToStructureDumper> result = ResolverHelper.resolveService( + return ResolverHelper.resolveMandatoryService( getCamelContextReference(), getCamelContextExtension().getBootstrapFactoryFinder(), ModelToStructureDumper.FACTORY, - ModelToStructureDumper.class); - - if (result.isPresent()) { - return result.get(); - } else { - throw new IllegalArgumentException( - "Cannot find ModelToStructureDumper on classpath. Add camel-core-engine to classpath."); - } + ModelToStructureDumper.class, + "camel-core-engine"); } @Override protected RestBindingJaxbDataFormatFactory createRestBindingJaxbDataFormatFactory() { - Optional<RestBindingJaxbDataFormatFactory> result = ResolverHelper.resolveService( + return ResolverHelper.resolveMandatoryService( getCamelContextReference(), getCamelContextExtension().getBootstrapFactoryFinder(), RestBindingJaxbDataFormatFactory.FACTORY, - RestBindingJaxbDataFormatFactory.class); - - if (result.isPresent()) { - return result.get(); - } else { - throw new IllegalArgumentException( - "Cannot find RestBindingJaxbDataFormatFactory on classpath. Add camel-jaxb to classpath."); - } + RestBindingJaxbDataFormatFactory.class, + "camel-jaxb"); } @Override protected RestBindingJacksonXmlDataFormatFactory createRestBindingJacksonXmlDataFormatFactory() { - Optional<RestBindingJacksonXmlDataFormatFactory> result = ResolverHelper.resolveService( + return ResolverHelper.resolveMandatoryService( getCamelContextReference(), getCamelContextExtension().getBootstrapFactoryFinder(), RestBindingJacksonXmlDataFormatFactory.FACTORY, - RestBindingJacksonXmlDataFormatFactory.class); - - if (result.isPresent()) { - return result.get(); - } else { - throw new IllegalArgumentException( - "Cannot find RestBindingJacksonXmlDataFormatFactory on classpath. Add camel-jacksonxml to classpath."); - } + RestBindingJacksonXmlDataFormatFactory.class, + "camel-jacksonxml"); } @Override @@ -712,17 +633,12 @@ public class SimpleCamelContext extends AbstractCamelContext { @Override protected RestRegistryFactory createRestRegistryFactory() { - Optional<RestRegistryFactory> result = ResolverHelper.resolveService( + return ResolverHelper.resolveMandatoryService( getCamelContextReference(), getCamelContextExtension().getBootstrapFactoryFinder(), RestRegistryFactory.FACTORY, - RestRegistryFactory.class); - - if (result.isPresent()) { - return result.get(); - } else { - throw new IllegalArgumentException("Cannot find RestRegistryFactory on classpath. Add camel-rest to classpath."); - } + RestRegistryFactory.class, + "camel-rest"); } @Override diff --git a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java index 7b56bdf513db..6731f16e5b79 100644 --- a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java +++ b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java @@ -21,7 +21,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.StringJoiner; import java.util.stream.Collectors; @@ -394,31 +393,23 @@ public class SimpleFunctionExpression extends LiteralExpression { } private Expression createSimpleAttachments(CamelContext camelContext, String function) { - Optional<SimpleLanguageFunctionFactory> factory = ResolverHelper.resolveService( + SimpleLanguageFunctionFactory factory = ResolverHelper.resolveMandatoryService( camelContext, camelContext.getCamelContextExtension().getBootstrapFactoryFinder(), SimpleLanguageFunctionFactory.FACTORY + "/camel-attachments", - SimpleLanguageFunctionFactory.class); - - if (factory.isEmpty()) { - throw new IllegalArgumentException( - "Cannot find SimpleLanguageFunctionFactory on classpath. Add camel-attachments to classpath."); - } - return factory.get().createFunction(camelContext, function, token.getIndex()); + SimpleLanguageFunctionFactory.class, + "camel-attachments"); + return factory.createFunction(camelContext, function, token.getIndex()); } private Expression createSimpleBase64(CamelContext camelContext, String function) { - Optional<SimpleLanguageFunctionFactory> factory = ResolverHelper.resolveService( + SimpleLanguageFunctionFactory factory = ResolverHelper.resolveMandatoryService( camelContext, camelContext.getCamelContextExtension().getBootstrapFactoryFinder(), SimpleLanguageFunctionFactory.FACTORY + "/camel-base64", - SimpleLanguageFunctionFactory.class); - - if (factory.isEmpty()) { - throw new IllegalArgumentException( - "Cannot find SimpleLanguageFunctionFactory on classpath. Add camel-base64 to classpath."); - } - return factory.get().createFunction(camelContext, function, token.getIndex()); + SimpleLanguageFunctionFactory.class, + "camel-base64"); + return factory.createFunction(camelContext, function, token.getIndex()); } private Expression createSimpleExpressionMessage(CamelContext camelContext, String function, boolean strict) { @@ -2594,31 +2585,23 @@ public class SimpleFunctionExpression extends LiteralExpression { } private String createCodeAttachments(CamelContext camelContext, String function) { - Optional<SimpleLanguageFunctionFactory> factory = ResolverHelper.resolveService( + SimpleLanguageFunctionFactory factory = ResolverHelper.resolveMandatoryService( camelContext, camelContext.getCamelContextExtension().getBootstrapFactoryFinder(), SimpleLanguageFunctionFactory.FACTORY + "/camel-attachments", - SimpleLanguageFunctionFactory.class); - - if (factory.isEmpty()) { - throw new IllegalArgumentException( - "Cannot find SimpleLanguageFunctionFactory on classpath. Add camel-attachments to classpath."); - } - return factory.get().createCode(camelContext, function, token.getIndex()); + SimpleLanguageFunctionFactory.class, + "camel-attachments"); + return factory.createCode(camelContext, function, token.getIndex()); } private String createCodeBase64(CamelContext camelContext, String function) { - Optional<SimpleLanguageFunctionFactory> factory = ResolverHelper.resolveService( + SimpleLanguageFunctionFactory factory = ResolverHelper.resolveMandatoryService( camelContext, camelContext.getCamelContextExtension().getBootstrapFactoryFinder(), SimpleLanguageFunctionFactory.FACTORY + "/camel-base64", - SimpleLanguageFunctionFactory.class); - - if (factory.isEmpty()) { - throw new IllegalArgumentException( - "Cannot find SimpleLanguageFunctionFactory on classpath. Add camel-base64 to classpath."); - } - return factory.get().createCode(camelContext, function, token.getIndex()); + SimpleLanguageFunctionFactory.class, + "camel-base64"); + return factory.createCode(camelContext, function, token.getIndex()); } private String createCodeExpressionMisc(CamelContext camelContext, String function) { diff --git a/core/camel-support/src/main/java/org/apache/camel/support/OAuthHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/OAuthHelper.java index 6648c82d5328..912c868d91d3 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/OAuthHelper.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/OAuthHelper.java @@ -40,14 +40,11 @@ public final class OAuthHelper { * @throws Exception if the factory is not found or token acquisition fails */ public static String resolveOAuthToken(CamelContext context, String profileName) throws Exception { - OAuthClientAuthenticationFactory factory = ResolverHelper.resolveService( + OAuthClientAuthenticationFactory factory = ResolverHelper.resolveMandatoryService( context, OAuthClientAuthenticationFactory.FACTORY, - OAuthClientAuthenticationFactory.class) - .orElseThrow(() -> new IllegalArgumentException( - "Cannot find OAuthClientAuthenticationFactory. " - + "Add camel-oauth to the classpath to use oauthProfile.")); - + OAuthClientAuthenticationFactory.class, + "camel-oauth"); return factory.resolveToken(context, profileName); } } diff --git a/core/camel-support/src/main/java/org/apache/camel/support/ResolverHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/ResolverHelper.java index 23cdf2e40b32..f39fa11880c2 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/ResolverHelper.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/ResolverHelper.java @@ -20,6 +20,7 @@ import java.util.Optional; import org.apache.camel.CamelContext; import org.apache.camel.Component; +import org.apache.camel.NoSuchServiceException; import org.apache.camel.spi.DataFormat; import org.apache.camel.spi.DataFormatFactory; import org.apache.camel.spi.FactoryFinder; @@ -148,6 +149,43 @@ public final class ResolverHelper { factoryKey, factoryClass); } + /** + * Create an instance of the given factory using the default factory finder + * + * @param camelContext the {@link CamelContext} + * @param factoryKey the key used top lookup the factory class + * @param factoryClass the type of the class + * @param jarName the JAR to add to the classpath if service is missing + * @return an instance of the given factory + * @throws NoSuchServiceException is thrown if service is not found + */ + public static <T> T resolveMandatoryService( + CamelContext camelContext, String factoryKey, Class<T> factoryClass, String jarName) + throws NoSuchServiceException { + return resolveMandatoryService(camelContext, camelContext.getCamelContextExtension().getDefaultFactoryFinder(), + factoryKey, factoryClass, jarName); + } + + /** + * Create an instance of the given factory using the default factory finder + * + * @param camelContext the {@link CamelContext} + * @param factoryFinder the factory finder to use + * @param factoryKey the key used top lookup the factory class + * @param factoryClass the type of the class + * @param jarName the JAR to add to the classpath if service is missing + * @return an instance of the given factory + * @throws NoSuchServiceException is thrown if service is not found + */ + public static <T> T resolveMandatoryService( + CamelContext camelContext, FactoryFinder factoryFinder, String factoryKey, Class<T> factoryClass, String jarName) + throws NoSuchServiceException { + return doResolveService( + camelContext, + factoryFinder, + factoryKey, factoryClass, false).orElseThrow(() -> new NoSuchServiceException(factoryKey, jarName)); + } + /** * Create an instance of the given factory using the default factory finder * @@ -175,12 +213,32 @@ public final class ResolverHelper { */ public static <T> Optional<T> resolveService( CamelContext camelContext, FactoryFinder factoryFinder, String factoryKey, Class<T> factoryClass) { + return doResolveService(camelContext, factoryFinder, factoryKey, factoryClass, true); + } + + /** + * Create an instance of the given factory. + * + * @param camelContext the {@link CamelContext} + * @param factoryFinder the {@link FactoryFinder} to use + * @param factoryKey the key used top lookup the factory class + * @param factoryClass the type of the class + * @param optional whether the service is optional + * @return an instance fo the given factory + */ + private static <T> Optional<T> doResolveService( + CamelContext camelContext, FactoryFinder factoryFinder, String factoryKey, Class<T> factoryClass, + boolean optional) { // use factory finder to find a custom implementations Class<?> type = null; try { - type = factoryFinder.findClass(factoryKey).orElse(null); + if (optional) { + type = factoryFinder.findOptionalClass(factoryKey).orElse(null); + } else { + type = factoryFinder.findClass(factoryKey).orElse(null); + } } catch (Exception e) { // ignore } diff --git a/dsl/camel-kamelet-main/src/generated/resources/camel-factoryfinder-known-dependencies.properties b/dsl/camel-kamelet-main/src/generated/resources/camel-factoryfinder-known-dependencies.properties new file mode 100644 index 000000000000..58a5c88156a1 --- /dev/null +++ b/dsl/camel-kamelet-main/src/generated/resources/camel-factoryfinder-known-dependencies.properties @@ -0,0 +1,64 @@ +## --------------------------------------------------------------------------- +## 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. +## --------------------------------------------------------------------------- + +META-INF/services/org/apache/camel/bean-processor-factory=camel:bean +META-INF/services/org/apache/camel/bean-proxy-factory=camel:bean +META-INF/services/org/apache/camel/cloud/consul-service-discovery=camel:consul +META-INF/services/org/apache/camel/cloud/dns-service-discovery=camel:dns +META-INF/services/org/apache/camel/cloud/http-service-expression=camel:http +META-INF/services/org/apache/camel/cloud/https-service-expression=camel:http +META-INF/services/org/apache/camel/cloud/kubernetes-service-discovery=camel:kubernetes +META-INF/services/org/apache/camel/cloud/netty-http-service-expression=camel:netty-http +META-INF/services/org/apache/camel/cloud/undertow-service-expression=camel:undertow +META-INF/services/org/apache/camel/cloud/zookeeper-service-discovery=camel:zookeeper +META-INF/services/org/apache/camel/csimple-compiler=camel:csimple-joor +META-INF/services/org/apache/camel/debugger-factory=camel:debug +META-INF/services/org/apache/camel/file-adapter-factory=camel:file +META-INF/services/org/apache/camel/groovy-script-compiler=camel:groovy +META-INF/services/org/apache/camel/headers-map-factory=camel:headersmap +META-INF/services/org/apache/camel/jandex-class-resolver=camel:jandex +META-INF/services/org/apache/camel/jmx-rest-definition-resolver=camel:openapi-java +META-INF/services/org/apache/camel/kafka-adapter-factory=camel:kafka +META-INF/services/org/apache/camel/kafka-resume-strategy=camel:kafka +META-INF/services/org/apache/camel/lra-saga-service=camel:lra +META-INF/services/org/apache/camel/mdc-service=camel:mdc +META-INF/services/org/apache/camel/micrometer-observability-tracer=camel:micrometer-observability +META-INF/services/org/apache/camel/micrometer-prometheus=camel:micrometer-prometheus +META-INF/services/org/apache/camel/mock-send-to-endpoint-strategy-factory=camel:mock +META-INF/services/org/apache/camel/oauth-client-authentication-factory=camel:oauth +META-INF/services/org/apache/camel/opentelemetry-tracer-2=camel:opentelemetry2 +META-INF/services/org/apache/camel/opentelemetry-tracer=camel:opentelemetry +META-INF/services/org/apache/camel/periodic-task/hashicorp-secret-refresh=camel:hashicorp-vault +META-INF/services/org/apache/camel/periodic-task/kubernetes-configmaps-refresh=camel:kubernetes +META-INF/services/org/apache/camel/periodic-task/kubernetes-secret-refresh=camel:kubernetes +META-INF/services/org/apache/camel/platform-http-engine=camel:platform-http-vertx +META-INF/services/org/apache/camel/platform-http-server=camel:platform-http-main +META-INF/services/org/apache/camel/platform-http/jolokia=camel:platform-http-jolokia +META-INF/services/org/apache/camel/platform-http/plugin-registry=camel:platform-http +META-INF/services/org/apache/camel/resilience4j-micrometer-factory=camel:resilience4j-micrometer +META-INF/services/org/apache/camel/resource-resolver/bean=camel:bean +META-INF/services/org/apache/camel/resource-resolver/gist=camel:resourceresolver-github +META-INF/services/org/apache/camel/resource-resolver/github=camel:resourceresolver-github +META-INF/services/org/apache/camel/rest-binding-jacksonxml-dataformat-factory=camel:jacksonxml +META-INF/services/org/apache/camel/rest-binding-jaxb-dataformat-factory=camel:jaxb +META-INF/services/org/apache/camel/rest-client-request-validator-factory=camel:openapi-validator +META-INF/services/org/apache/camel/rest-client-response-validator-factory=camel:openapi-validator +META-INF/services/org/apache/camel/rest-registry-factory=camel:rest +META-INF/services/org/apache/camel/startup-step-recorder=camel:jfr +META-INF/services/org/apache/camel/telemetry-dev-tracer=camel:telemetry-dev +META-INF/services/org/apache/camel/thread-factory-listener=camel:opentelemetry +META-INF/services/org/apache/camel/write-ahead-resume-strategy=camel:wal 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 91ace180b2b7..f31ff10ddcae 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 @@ -43,6 +43,7 @@ import org.apache.camel.main.download.BasePackageScanDownloadListener; import org.apache.camel.main.download.CamelCustomClassLoader; import org.apache.camel.main.download.CircuitBreakerDownloader; import org.apache.camel.main.download.CommandLineDependencyDownloader; +import org.apache.camel.main.download.DependencyDownloadFactoryFinderResolver; import org.apache.camel.main.download.DependencyDownloaderClassLoader; import org.apache.camel.main.download.DependencyDownloaderClassResolver; import org.apache.camel.main.download.DependencyDownloaderComponentResolver; @@ -631,6 +632,12 @@ public class KameletMain extends MainCommandLineSupport { String springBootVersion = (String) getInitialProperties().get(getInstanceType() + ".springBootVersion"); String quarkusVersion = (String) getInitialProperties().get(getInstanceType() + ".quarkusVersion"); + // factory finder that can autodownload from known dependencies + KnownDependenciesResolver ffKnownDeps = new KnownDependenciesResolver(answer, springBootVersion, quarkusVersion); + ffKnownDeps.loadKnownFactoryFinderDependencies(); + DependencyDownloadFactoryFinderResolver fr = new DependencyDownloadFactoryFinderResolver(answer, ffKnownDeps); + answer.getCamelContextExtension().addContextPlugin(FactoryFinderResolver.class, fr); + KnownDependenciesResolver knownDeps = new KnownDependenciesResolver(answer, springBootVersion, quarkusVersion); knownDeps.loadKnownDependencies(); DependencyDownloaderPropertyBindingListener listener diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloadFactoryFinder.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloadFactoryFinder.java new file mode 100644 index 000000000000..f91038333b12 --- /dev/null +++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloadFactoryFinder.java @@ -0,0 +1,55 @@ +/* + * 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.util.Optional; + +import org.apache.camel.CamelContext; +import org.apache.camel.impl.engine.DefaultFactoryFinder; +import org.apache.camel.spi.ClassResolver; +import org.apache.camel.spi.FactoryFinder; +import org.apache.camel.tooling.maven.MavenGav; + +public class DependencyDownloadFactoryFinder extends DefaultFactoryFinder { + + private final KnownDependenciesResolver knownDependenciesResolver; + private final DependencyDownloader downloader; + + public DependencyDownloadFactoryFinder(CamelContext camelContext, ClassResolver classResolver, String resourcePath, + KnownDependenciesResolver knownDependenciesResolver) { + super(classResolver, resourcePath); + this.knownDependenciesResolver = knownDependenciesResolver; + this.downloader = camelContext.hasService(DependencyDownloader.class); + } + + @Override + public Optional<Class<?>> findClass(String key) { + // this is not optional so we can auto download the JAR as it's intended to be on the classpath + MavenGav gav = knownDependenciesResolver.mavenGavForClass(FactoryFinder.DEFAULT_PATH + key); + if (gav != null) { + downloadLoader(gav.getGroupId(), gav.getArtifactId(), gav.getVersion()); + } + return super.findClass(key); + } + + private void downloadLoader(String groupId, String artifactId, String version) { + if (!downloader.alreadyOnClasspath(groupId, artifactId, version)) { + downloader.downloadDependency(groupId, artifactId, version); + } + } + +} diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloadFactoryFinderResolver.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloadFactoryFinderResolver.java new file mode 100644 index 000000000000..0502df7225d3 --- /dev/null +++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloadFactoryFinderResolver.java @@ -0,0 +1,44 @@ +/* + * 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 org.apache.camel.CamelContext; +import org.apache.camel.impl.engine.BootstrapFactoryFinder; +import org.apache.camel.spi.ClassResolver; +import org.apache.camel.spi.FactoryFinder; +import org.apache.camel.spi.FactoryFinderResolver; + +public class DependencyDownloadFactoryFinderResolver implements FactoryFinderResolver { + + private final CamelContext camelContext; + private final KnownDependenciesResolver knownDeps; + + public DependencyDownloadFactoryFinderResolver(CamelContext camelContext, KnownDependenciesResolver knownDeps) { + this.camelContext = camelContext; + this.knownDeps = knownDeps; + } + + @Override + public FactoryFinder resolveBootstrapFactoryFinder(ClassResolver classResolver, String resourcePath) { + return new BootstrapFactoryFinder(classResolver, resourcePath); + } + + @Override + public FactoryFinder resolveFactoryFinder(ClassResolver classResolver, String resourcePath) { + return new DependencyDownloadFactoryFinder(camelContext, classResolver, resourcePath, knownDeps); + } +} diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/KnownDependenciesResolver.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/KnownDependenciesResolver.java index 35c4c8f962cd..cae1d090987a 100644 --- a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/KnownDependenciesResolver.java +++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/KnownDependenciesResolver.java @@ -44,6 +44,10 @@ public final class KnownDependenciesResolver { doLoadKnownDependencies("camel-component-known-dependencies.properties"); } + public void loadKnownFactoryFinderDependencies() { + doLoadKnownDependencies("camel-factoryfinder-known-dependencies.properties"); + } + private void doLoadKnownDependencies(String name) { try { Enumeration<URL> resources = getClass().getClassLoader().getResources(name); diff --git a/dsl/camel-kamelet-main/src/main/resources/camel-main-known-dependencies.properties b/dsl/camel-kamelet-main/src/main/resources/camel-main-known-dependencies.properties index 1caa9011b5c4..1dc329a60c4c 100644 --- a/dsl/camel-kamelet-main/src/main/resources/camel-main-known-dependencies.properties +++ b/dsl/camel-kamelet-main/src/main/resources/camel-main-known-dependencies.properties @@ -21,6 +21,18 @@ org.springframework.stereotype.Component = camel:spring org.springframework.beans.factory.annotation.Qualifier = camel:spring org.springframework.stereotype.Service = camel:spring org.springframework.beans.factory.annotation.Value = camel:spring +org.springframework.amqp.rabbit.connection.CachingConnectionFactory = camel:spring-rabbitmq +org.springframework.jdbc.datasource.SimpleDriverDataSource = camel:sql +spring.datasource.url = org.springframework.boot:spring-boot-starter-jdbc:${spring-boot-version} + +quarkus.datasource.db-kind\=db2 = io.quarkus:quarkus-jdbc-db2:${quarkus-version} +quarkus.datasource.db-kind\=derby = io.quarkus:quarkus-jdbc-derby:${quarkus-version} +quarkus.datasource.db-kind\=h2 = io.quarkus:quarkus-jdbc-h2:${quarkus-version} +quarkus.datasource.db-kind\=mariadb = io.quarkus:quarkus-jdbc-mariadb:${quarkus-version} +quarkus.datasource.db-kind\=mssql = io.quarkus:quarkus-jdbc-mssql:${quarkus-version} +quarkus.datasource.db-kind\=mysql = io.quarkus:quarkus-jdbc-mysql:${quarkus-version} +quarkus.datasource.db-kind\=oracle = io.quarkus:quarkus-jdbc-oracle:${quarkus-version} +quarkus.datasource.db-kind\=postgresql = io.quarkus:quarkus-jdbc-postgresql:${quarkus-version} jakarta.enterprise.context.ApplicationScoped = io.quarkus:quarkus-core:${quarkus-version} jakarta.inject.Inject = io.quarkus:quarkus-core:${quarkus-version} @@ -29,39 +41,23 @@ jakarta.enterprise.inject.Produces = io.quarkus:quarkus-core:${quarkus-version} jakarta.inject.Singleton = io.quarkus:quarkus-core:${quarkus-version} org.eclipse.microprofile.config.inject.ConfigProperty = camel:microprofile-config +META-INF/services/org/apache/camel/modelxml-dumper = camel:xml-io +META-INF/services/org/apache/camel/modelyaml-dumper = camel:yaml-io +META-INF/services/org/apache/camel/cron/cron-service = camel:quartz + com.amazon.redshift.jdbc.Driver = com.amazon.redshift:redshift-jdbc42:2.1.0.33 com.microsoft.sqlserver.jdbc.SQLServerDriver = com.microsoft.sqlserver:mssql-jdbc:12.10.0.jre11 com.mysql.cj.jdbc.Driver = com.mysql:mysql-connector-j:${debezium-mysql-connector-version} +com.zaxxer.hikari.HikariDataSource = com.zaxxer:HikariCP:6.3.0 net.sf.saxon.xpath.XPathFactoryImpl = camel:saxon -org.springframework.amqp.rabbit.connection.CachingConnectionFactory = camel:spring-rabbitmq +oracle.jdbc.driver.OracleDriver = com.oracle.database.jdbc:ojdbc17:23.8.0.25.04 org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory = org.apache.activemq:artemis-jakarta-client-all:${activemq-artemis-version} -org.messaginghub.pooled.jms.JmsPoolConnectionFactory = org.messaginghub:pooled-jms:${pooled-jms-version} +org.apache.camel.component.activemq.ActiveMQComponent\:embedded\=true = org.apache.activemq:activemq-broker:${activemq-version} +org.apache.camel.component.activemq6.ActiveMQComponent\:embedded\=true = org.apache.activemq:activemq-broker:${activemq6-version} +org.apache.camel.component.cxf.jaxrs.CxfRsEndpoint = camel:cxf-rest +org.apache.camel.component.cxf.jaxws.CxfEndpoint = camel:cxf-soap org.apache.commons.dbcp2.BasicDataSource = org.apache.commons:commons-dbcp2:${commons-dbcp2-version} org.apache.qpid.jms.JmsConnectionFactory = org.apache.qpid:qpid-jms-client:${qpid-jms-client-version} +org.messaginghub.pooled.jms.JmsPoolConnectionFactory = org.messaginghub:pooled-jms:${pooled-jms-version} org.postgresql.Driver = org.postgresql:postgresql:${pgjdbc-driver-version} org.postgresql.ds.PGSimpleDataSource = org.postgresql:postgresql:${pgjdbc-driver-version} -org.apache.camel.component.cxf.jaxws.CxfEndpoint = camel:cxf-soap -org.apache.camel.component.cxf.jaxrs.CxfRsEndpoint = camel:cxf-rest -META-INF/services/org/apache/camel/oauth-client-authentication-factory = camel:oauth -META-INF/services/org/apache/camel/restapi/openapi = camel:openapi-java -META-INF/services/org/apache/camel/modelxml-dumper = camel:xml-io -META-INF/services/org/apache/camel/modelyaml-dumper = camel:yaml-io -META-INF/services/org/apache/camel/micrometer-prometheus = camel:micrometer-prometheus -META-INF/services/org/apache/camel/cron/cron-service = camel:quartz -META-INF/services/org/apache/camel/platform-http/jolokia = camel:camel-platform-http-jolokia -META-INF/services/org/apache/camel/jandex-class-resolver = camel:jandex -META-INF/services/org/apache/camel/groovy-script-compiler = camel:groovy -org.apache.camel.component.activemq.ActiveMQComponent\:embedded\=true = org.apache.activemq:activemq-broker:${activemq-version} -org.apache.camel.component.activemq6.ActiveMQComponent\:embedded\=true = org.apache.activemq:activemq-broker:${activemq6-version} -spring.datasource.url = org.springframework.boot:spring-boot-starter-jdbc:${spring-boot-version} -quarkus.datasource.db-kind\=db2 = io.quarkus:quarkus-jdbc-db2:${quarkus-version} -quarkus.datasource.db-kind\=derby = io.quarkus:quarkus-jdbc-derby:${quarkus-version} -quarkus.datasource.db-kind\=h2 = io.quarkus:quarkus-jdbc-h2:${quarkus-version} -quarkus.datasource.db-kind\=mariadb = io.quarkus:quarkus-jdbc-mariadb:${quarkus-version} -quarkus.datasource.db-kind\=mssql = io.quarkus:quarkus-jdbc-mssql:${quarkus-version} -quarkus.datasource.db-kind\=mysql = io.quarkus:quarkus-jdbc-mysql:${quarkus-version} -quarkus.datasource.db-kind\=oracle = io.quarkus:quarkus-jdbc-oracle:${quarkus-version} -quarkus.datasource.db-kind\=postgresql = io.quarkus:quarkus-jdbc-postgresql:${quarkus-version} -org.springframework.jdbc.datasource.SimpleDriverDataSource = camel:sql -oracle.jdbc.driver.OracleDriver = com.oracle.database.jdbc:ojdbc17:23.8.0.25.04 -com.zaxxer.hikari.HikariDataSource = com.zaxxer:HikariCP:6.3.0 \ No newline at end of file diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareKameletMainMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareKameletMainMojo.java index aff5b0d3ec59..14fc2003efeb 100644 --- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareKameletMainMojo.java +++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareKameletMainMojo.java @@ -27,6 +27,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.TreeSet; import java.util.stream.Collectors; @@ -46,6 +47,7 @@ import org.apache.maven.project.MavenProject; import org.codehaus.plexus.build.BuildContext; import static org.apache.camel.maven.packaging.generics.PackagePluginUtils.joinHeaderAndSource; +import static org.apache.camel.tooling.util.PackageHelper.findCamelDirectory; import static org.apache.camel.tooling.util.PackageHelper.loadText; /** @@ -71,6 +73,9 @@ public class PrepareKameletMainMojo extends AbstractMojo { @Parameter(defaultValue = "${project.directory}/../../../catalog/camel-catalog") protected File catalogDir; + @Parameter(defaultValue = "${project.directory}/../../../components") + protected File componentsDir; + @Parameter(defaultValue = "src/generated/") protected File genDir; @@ -95,6 +100,12 @@ public class PrepareKameletMainMojo extends AbstractMojo { } catch (Exception e) { throw new MojoFailureException("Error updating camel-component-known-dependencies.properties", e); } + + try { + updateKnownFactoryFinders(); + } catch (Exception e) { + throw new MojoFailureException("Error updating camel-factoryfinder-known-dependencies.properties", e); + } } protected void updateKnownDependencies() throws Exception { @@ -143,6 +154,27 @@ public class PrepareKameletMainMojo extends AbstractMojo { writeSourceIfChanged(source, "resources", "camel-component-known-dependencies.properties", genDir); } + protected void updateKnownFactoryFinders() throws Exception { + List<String> lines = findFactoryFinder(componentsDir); + + // remove duplicate + lines = lines.stream().distinct().collect(Collectors.toList()); + // and sort + Collections.sort(lines); + + getLog().info("Found " + lines.size() + " FactoryFinder @JdkService"); + + // load license header + try (InputStream is = getClass().getClassLoader().getResourceAsStream("license-header.txt")) { + this.licenseHeader = loadText(is); + } catch (Exception e) { + throw new MojoFailureException("Error loading license-header.txt file", e); + } + + String source = String.join("\n", lines) + "\n"; + writeSourceIfChanged(source, "resources", "camel-factoryfinder-known-dependencies.properties", genDir); + } + protected boolean writeSourceIfChanged(String source, String filePath, String fileName, File outputDir) throws MojoFailureException { Path target = outputDir.toPath().resolve(filePath).resolve(fileName); @@ -178,4 +210,44 @@ public class PrepareKameletMainMojo extends AbstractMojo { } } + private static List<String> findFactoryFinder(File rootDir) { + List<String> answer = new ArrayList<>(); + + for (File f : Objects.requireNonNull(rootDir.listFiles())) { + String artifact = f.getName(); + if (artifact.startsWith("camel-")) { + artifact = artifact.substring(6); + } + if (f.isDirectory()) { + File fd = findCamelDirectory(f, "src/generated/resources/META-INF/services/org/apache/camel/"); + if (fd != null && fd.isDirectory()) { + findFactoryFinder(answer, artifact, fd, null); + } + } + } + + return answer; + } + + private static void findFactoryFinder(List<String> answer, String artifact, File dir, String subdir) { + for (File sf : Objects.requireNonNull(dir.listFiles())) { + if (sf.isFile() && !sf.getName().contains(".") && acceptFactoryFinderFile(sf.getName())) { + // service marker file + String path = subdir != null ? subdir + "/" + sf.getName() : sf.getName(); + answer.add("META-INF/services/org/apache/camel/" + path + "=camel:" + artifact); + } else if (sf.isDirectory() && acceptFactoryFinderSubDir(sf.getName())) { + findFactoryFinder(answer, artifact, sf, sf.getName()); + } + } + } + + private static boolean acceptFactoryFinderSubDir(String name) { + return "cloud".equals(name) || "platform-http".equals(name) || "periodic-task".equals(name) + || "resource-resolver".equals(name); + } + + private static boolean acceptFactoryFinderFile(String name) { + return !"TypeConverterLoader".equals(name) && !"reactive-executor".equals(name) && !"thread-pool-factory".equals(name); + } + }
