ppalaga commented on a change in pull request #1344: URL: https://github.com/apache/camel-quarkus/pull/1344#discussion_r440083716
########## File path: extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelNativeImageProcessor.java ########## @@ -0,0 +1,298 @@ +/* + * 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.quarkus.core.deployment; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import io.quarkus.deployment.ApplicationArchive; +import io.quarkus.deployment.annotations.BuildProducer; +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.builditem.ApplicationArchivesBuildItem; +import io.quarkus.deployment.builditem.CombinedIndexBuildItem; +import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem; +import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; +import io.quarkus.deployment.builditem.nativeimage.ReflectiveMethodBuildItem; +import org.apache.camel.CamelContext; +import org.apache.camel.Component; +import org.apache.camel.Consumer; +import org.apache.camel.Converter; +import org.apache.camel.Endpoint; +import org.apache.camel.Producer; +import org.apache.camel.TypeConverter; +import org.apache.camel.impl.engine.DefaultComponentResolver; +import org.apache.camel.impl.engine.DefaultDataFormatResolver; +import org.apache.camel.impl.engine.DefaultLanguageResolver; +import org.apache.camel.quarkus.core.CamelConfig; +import org.apache.camel.quarkus.core.CamelConfig.ReflectionConfig; +import org.apache.camel.quarkus.core.CamelConfig.ResourcesConfig; +import org.apache.camel.quarkus.core.CamelConfigFlags; +import org.apache.camel.quarkus.core.deployment.spi.CamelRoutesBuilderClassBuildItem; +import org.apache.camel.quarkus.core.deployment.spi.CamelServiceBuildItem; +import org.apache.camel.quarkus.core.deployment.spi.CamelServicePatternBuildItem; +import org.apache.camel.quarkus.core.deployment.util.CamelSupport; +import org.apache.camel.quarkus.core.deployment.util.PathFilter; +import org.apache.camel.spi.DataFormat; +import org.apache.camel.spi.ExchangeFormatter; +import org.apache.camel.spi.PropertiesComponent; +import org.apache.camel.spi.ScheduledPollConsumerScheduler; +import org.apache.camel.spi.StreamCachingStrategy; +import org.apache.camel.support.CamelContextHelper; +import org.jboss.jandex.AnnotationTarget.Kind; +import org.jboss.jandex.AnnotationValue; +import org.jboss.jandex.ClassInfo; +import org.jboss.jandex.DotName; +import org.jboss.jandex.IndexView; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.apache.commons.lang3.ClassUtils.getPackageName; + +public class CamelNativeImageProcessor { + private static final Logger LOGGER = LoggerFactory.getLogger(CamelNativeImageProcessor.class); + + private static final List<Class<?>> CAMEL_REFLECTIVE_CLASSES = Arrays.asList( + Endpoint.class, + Consumer.class, + Producer.class, + TypeConverter.class, + ExchangeFormatter.class, + ScheduledPollConsumerScheduler.class, + Component.class, + CamelContext.class, + StreamCachingStrategy.class, + StreamCachingStrategy.SpoolUsedHeapMemoryLimit.class, + PropertiesComponent.class, + DataFormat.class); + + @BuildStep + void reflectiveItems( + CombinedIndexBuildItem combinedIndex, + BuildProducer<ReflectiveClassBuildItem> reflectiveClass, + BuildProducer<ReflectiveMethodBuildItem> reflectiveMethod) { + + final IndexView view = combinedIndex.getIndex(); + + CAMEL_REFLECTIVE_CLASSES.stream() + .map(Class::getName) + .map(DotName::createSimple) + .map(view::getAllKnownImplementors) + .flatMap(Collection::stream) + .filter(CamelSupport::isPublic) + .forEach(v -> reflectiveClass.produce(new ReflectiveClassBuildItem(true, false, v.name().toString()))); Review comment: A side note about a possible future refactoring: Producing a single ReflectiveClassBuildItem containing multiple class names seems to be more effective than producing multiple ReflectiveClassBuildItems containing single class name each. We have several sites like this. ########## File path: docs/modules/ROOT/pages/extensions/main.adoc ########## @@ -0,0 +1,22 @@ +// Do not edit directly! +// This file was generated by camel-quarkus-package-maven-plugin:update-extension-doc-page + +[[main]] += Main + +[.badges] +[.badge-key]##Since Camel Quarkus##[.badge-version]##1.0.0-CR3## [.badge-key]##JVM##[.badge-supported]##supported## [.badge-key]##Native##[.badge-supported]##supported## + +Camel Main Review comment: Would you mind adding a more informative `<description>` to the runtime pom.xml so that users get an idea what it is good for? ########## File path: extensions-core/main/runtime/src/main/java/org/apache/camel/quarkus/main/CamelMainRoutesCollector.java ########## @@ -90,7 +91,7 @@ public XMLRoutesDefinitionLoader getXmlRoutesLoader() { List<RestsDefinition> answer = new ArrayList<>(); PackageScanResourceResolver resolver = camelContext.adapt(ExtendedCamelContext.class).getPackageScanResourceResolver(); - for (String part : directory.split(",")) { + for (String part : directory.split(",", -1)) { Review comment: Why do we need the empty trailing string here? ########## File path: extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelConfig.java ########## @@ -44,29 +44,25 @@ @ConfigItem public RuntimeCatalogConfig runtimeCatalog; + /** + * Build time configuration options for routes discovery. + */ + @ConfigItem + public RoutesDiscoveryConfig routesDiscovery; + /** * Build time configuration options related to the building of native executable. */ @ConfigItem(name = "native") public NativeConfig native_; @ConfigGroup - public static class MainConfig { + public static class BootstrapConfig { /** - * Enable {@code camel-main}. If {@code true}, routes are automatically - * loaded and started and the entire lifecycle of the Camel Context is - * under the control of the {@code camel-main} component. Otherwise, the - * application developer is responsible for performing all the mentioned - * tasks. + * Enable bootstrapping the {@link CamelRuntime}. Review comment: Explaining in more detail what it does or add a link to a resource that explains it would be nice. ########## File path: extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/spi/CamelRuntimeTaskBuildItem.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.quarkus.core.deployment.spi; + +import io.quarkus.builder.item.MultiBuildItem; + +/** + * A symbolic class that represents a runtime task. Review comment: I wonder what `symbolic` means here? I never heart of runtime tasks in the context of Camel Quarkus. Could you please add a sentence or example to get an idea what it is? ########## File path: extensions-core/main/runtime/src/main/java/org/apache/camel/quarkus/main/CamelMainRoutesCollector.java ########## @@ -66,7 +67,7 @@ public XMLRoutesDefinitionLoader getXmlRoutesLoader() { List<RoutesDefinition> answer = new ArrayList<>(); PackageScanResourceResolver resolver = camelContext.adapt(ExtendedCamelContext.class).getPackageScanResourceResolver(); - for (String part : directory.split(",")) { + for (String part : directory.split(",", -1)) { Review comment: Why do we need the empty trailing string here? ########## File path: extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelContextProcessor.java ########## @@ -0,0 +1,160 @@ +/* + * 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.quarkus.core.deployment; + +import java.util.List; + +import io.quarkus.arc.deployment.BeanContainerBuildItem; +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.annotations.ExecutionTime; +import io.quarkus.deployment.annotations.Overridable; +import io.quarkus.deployment.annotations.Record; +import io.quarkus.deployment.builditem.ServiceStartBuildItem; +import io.quarkus.runtime.RuntimeValue; +import org.apache.camel.CamelContext; +import org.apache.camel.quarkus.core.CamelConfig; +import org.apache.camel.quarkus.core.CamelConfigFlags; +import org.apache.camel.quarkus.core.CamelContextRecorder; +import org.apache.camel.quarkus.core.CamelRuntime; +import org.apache.camel.quarkus.core.deployment.spi.CamelContextBuildItem; +import org.apache.camel.quarkus.core.deployment.spi.CamelContextCustomizerBuildItem; +import org.apache.camel.quarkus.core.deployment.spi.CamelFactoryFinderResolverBuildItem; +import org.apache.camel.quarkus.core.deployment.spi.CamelModelJAXBContextFactoryBuildItem; +import org.apache.camel.quarkus.core.deployment.spi.CamelModelToXMLDumperBuildItem; +import org.apache.camel.quarkus.core.deployment.spi.CamelRegistryBuildItem; +import org.apache.camel.quarkus.core.deployment.spi.CamelRoutesBuilderClassBuildItem; +import org.apache.camel.quarkus.core.deployment.spi.CamelRoutesLoaderBuildItems; +import org.apache.camel.quarkus.core.deployment.spi.CamelRuntimeBuildItem; +import org.apache.camel.quarkus.core.deployment.spi.CamelRuntimeTaskBuildItem; +import org.apache.camel.quarkus.core.deployment.spi.CamelTypeConverterRegistryBuildItem; +import org.apache.camel.quarkus.core.deployment.spi.ContainerBeansBuildItem; +import org.apache.camel.quarkus.core.deployment.spi.RuntimeCamelContextCustomizerBuildItem; +import org.apache.camel.quarkus.core.deployment.util.CamelSupport; +import org.apache.camel.spi.ModelJAXBContextFactory; +import org.apache.camel.spi.TypeConverterRegistry; + +public class CamelContextProcessor { + /** + * This build step is responsible to assemble a {@link CamelContext} instance. + * + * @param beanContainer a reference to a fully initialized CDI bean container + * @param recorder the recorder. + * @param registry a reference to a {@link org.apache.camel.spi.Registry}. + * @param typeConverterRegistry a reference to a {@link TypeConverterRegistry}. + * @param modelJAXBContextFactory a list of known {@link ModelJAXBContextFactory}. + * @param xmlLoader a list of known {@link org.apache.camel.spi.XMLRoutesDefinitionLoader}. + * @param modelDumper a list of known {@link CamelModelToXMLDumperBuildItem}. + * @param factoryFinderResolver a list of known {@link org.apache.camel.spi.FactoryFinderResolver}. + * @param customizers a list of {@link org.apache.camel.quarkus.core.CamelContextCustomizer} used to + * customize the {@link CamelContext} at {@link ExecutionTime#STATIC_INIT}. + * @return a build item holding an instance of a {@link CamelContext} + */ + @Record(ExecutionTime.STATIC_INIT) + @BuildStep + CamelContextBuildItem context( + BeanContainerBuildItem beanContainer, + CamelContextRecorder recorder, + CamelRegistryBuildItem registry, + CamelTypeConverterRegistryBuildItem typeConverterRegistry, + CamelModelJAXBContextFactoryBuildItem modelJAXBContextFactory, + CamelRoutesLoaderBuildItems.Xml xmlLoader, + CamelModelToXMLDumperBuildItem modelDumper, + CamelFactoryFinderResolverBuildItem factoryFinderResolver, + List<CamelContextCustomizerBuildItem> customizers, + CamelConfig config) { + + RuntimeValue<CamelContext> context = recorder.createContext( + registry.getRegistry(), + typeConverterRegistry.getRegistry(), + modelJAXBContextFactory.getContextFactory(), + xmlLoader.getLoader(), + modelDumper.getValue(), + factoryFinderResolver.getFactoryFinderResolver(), + beanContainer.getValue(), + CamelSupport.getCamelVersion(), + config); + + for (CamelContextCustomizerBuildItem customizer : customizers) { + recorder.customize(context, customizer.get()); + } + + return new CamelContextBuildItem(context); + } + + /** + * This build steps assembles the default implementation of a {@link CamelRuntime} responsible to bootstrap + * Camel. + * <p> + * This implementation provides the minimal features for a fully functional and ready to use {@link CamelRuntime} by + * loading all the discoverable {@link org.apache.camel.RoutesBuilder} into the auto-configured {@link CamelContext} + * but does not perform any advanced set-up such as: + * <ul> + * <li>auto-configure components/languages/data-formats through properties which is then under user responsibility + * <li>take control of the application life-cycle + * </ul> + * <p> + * For advanced auto-configuration capabilities add camel-quarkus-main to the list of dependencies. Review comment: I appreciate the comment! ########## File path: extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/spi/CamelRuntimeBuildItem.java ########## @@ -18,19 +18,16 @@ import io.quarkus.builder.item.SimpleBuildItem; import io.quarkus.runtime.RuntimeValue; -import org.apache.camel.spi.ReactiveExecutor; +import org.apache.camel.quarkus.core.CamelRuntime; -/** - * Holds the {@link ReactiveExecutor} {@link RuntimeValue}. - */ -public final class CamelReactiveExecutorBuildItem extends SimpleBuildItem { - private final RuntimeValue<ReactiveExecutor> instance; +public final class CamelRuntimeBuildItem extends SimpleBuildItem { + private final RuntimeValue<CamelRuntime> runtime; - public CamelReactiveExecutorBuildItem(RuntimeValue<ReactiveExecutor> instance) { - this.instance = instance; + public CamelRuntimeBuildItem(RuntimeValue<CamelRuntime> runtime) { + this.runtime = runtime; } - public RuntimeValue<ReactiveExecutor> getInstance() { - return instance; + public RuntimeValue<CamelRuntime> get() { + return runtime; Review comment: Please next time put this kind of refactorings in a separate commit. ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org