This is an automated email from the ASF dual-hosted git repository. gnodet pushed a commit to branch lightweight in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
commit 72d6f21dd57a898efedc683035a49c4be2292dd2 Author: Guillaume Nodet <[email protected]> AuthorDate: Wed Mar 25 08:27:53 2020 +0100 Leverage lightweight context and fix wrt latest Camel changes --- docs/modules/ROOT/pages/cdi.adoc | 2 +- .../src/main/java/org/acme/timer/TimerRoute.java | 2 +- .../src/main/kotlin/org/acme/timer/routes.kt | 2 +- .../src/main/java/org/acme/timer/TimerRoute.java | 2 +- .../src/main/resources/routes/my-routes.xml | 2 +- .../src/main/java/org/acme/timer/TimerRoute.java | 2 +- .../graal/SubstituteCachingServiceDiscovery.java | 56 --- .../quarkus/core/deployment/BuildProcessor.java | 53 ++- .../org/apache/camel/quarkus/core/BaseModel.java | 364 ------------------ .../org/apache/camel/quarkus/core/CamelConfig.java | 7 + .../org/apache/camel/quarkus/core/CamelMain.java | 24 +- .../camel/quarkus/core/CamelMainRecorder.java | 13 +- .../apache/camel/quarkus/core/CamelRecorder.java | 83 ++++- .../camel/quarkus/core/CamelRoutesCollector.java | 5 + .../quarkus/core/DisabledValidateReifier.java | 6 +- .../camel/quarkus/core/FastCamelContext.java | 263 ++++++++----- .../org/apache/camel/quarkus/core/FastModel.java | 413 +++++++++++++-------- .../camel/quarkus/core/FastTypeConverter.java | 1 - .../java/org/apache/camel/quarkus/core/Flags.java | 12 +- .../executor/deployment/BuildProcessor.java | 2 +- .../component/xml/jaxb/XmlJaxbRecorder.java | 2 +- .../org/apache/camel/quarkus/kotlin/RoutesDSL.kt | 2 +- .../deployment/MicroProfileHealthProcessor.java | 3 + .../component/qute/QuteComponentConfigurer.java | 32 +- .../component/qute/QuteEndpointConfigurer.java | 36 +- pom.xml | 2 +- poms/bom/pom.xml | 45 +++ 27 files changed, 720 insertions(+), 716 deletions(-) diff --git a/docs/modules/ROOT/pages/cdi.adoc b/docs/modules/ROOT/pages/cdi.adoc index e9f1420..f858973 100644 --- a/docs/modules/ROOT/pages/cdi.adoc +++ b/docs/modules/ROOT/pages/cdi.adoc @@ -15,7 +15,7 @@ import org.eclipse.microprofile.config.inject.ConfigProperty; @ApplicationScoped <1> public class TimerRoute extends RouteBuilder { - @ConfigProperty(name = "timer.period", defaultValue = "1s") <2> + @ConfigProperty(name = "timer.period", defaultValue = "1000") <2> String period; @Inject diff --git a/examples/timer-log-cdi/src/main/java/org/acme/timer/TimerRoute.java b/examples/timer-log-cdi/src/main/java/org/acme/timer/TimerRoute.java index 8052005..0e0056f 100644 --- a/examples/timer-log-cdi/src/main/java/org/acme/timer/TimerRoute.java +++ b/examples/timer-log-cdi/src/main/java/org/acme/timer/TimerRoute.java @@ -32,7 +32,7 @@ import org.eclipse.microprofile.config.inject.ConfigProperty; public class TimerRoute extends RouteBuilder { /** {@code timer.period} is defined in {@code src/main/resources/application.properties} */ - @ConfigProperty(name = "timer.period", defaultValue = "1s") + @ConfigProperty(name = "timer.period", defaultValue = "1000") String period; /** An injected bean */ diff --git a/examples/timer-log-kotlin/src/main/kotlin/org/acme/timer/routes.kt b/examples/timer-log-kotlin/src/main/kotlin/org/acme/timer/routes.kt index 129a6ef..467bab6 100644 --- a/examples/timer-log-kotlin/src/main/kotlin/org/acme/timer/routes.kt +++ b/examples/timer-log-kotlin/src/main/kotlin/org/acme/timer/routes.kt @@ -25,7 +25,7 @@ import javax.enterprise.inject.Produces class Routes { @Produces fun myRoutes() = routes { - from("timer:foo?period=1s") + from("timer:foo?period=1000") .process { e: Exchange -> e.message.body = "Hello from Kotlin!" } .log("\${body}") } diff --git a/examples/timer-log-spring/src/main/java/org/acme/timer/TimerRoute.java b/examples/timer-log-spring/src/main/java/org/acme/timer/TimerRoute.java index 21c07bd..a7cdd61 100644 --- a/examples/timer-log-spring/src/main/java/org/acme/timer/TimerRoute.java +++ b/examples/timer-log-spring/src/main/java/org/acme/timer/TimerRoute.java @@ -31,7 +31,7 @@ public class TimerRoute extends RouteBuilder { * {@code timer.period} is defined in {@code src/main/resources/application.properties} */ @Value("timer.period") - String period = "1s"; + String period = "1000"; /** * An injected bean diff --git a/examples/timer-log-xml/src/main/resources/routes/my-routes.xml b/examples/timer-log-xml/src/main/resources/routes/my-routes.xml index 42fd73f..ed63c39 100644 --- a/examples/timer-log-xml/src/main/resources/routes/my-routes.xml +++ b/examples/timer-log-xml/src/main/resources/routes/my-routes.xml @@ -24,7 +24,7 @@ http://camel.apache.org/schema/spring/camel-spring.xsd"> <route id="xml-route"> - <from uri="timer:from-xml?period=1s"/> + <from uri="timer:from-xml?period=1000"/> <log message="Hello XML!"/> </route> diff --git a/examples/timer-log/src/main/java/org/acme/timer/TimerRoute.java b/examples/timer-log/src/main/java/org/acme/timer/TimerRoute.java index 70b8bd7..0a3b0b9 100644 --- a/examples/timer-log/src/main/java/org/acme/timer/TimerRoute.java +++ b/examples/timer-log/src/main/java/org/acme/timer/TimerRoute.java @@ -22,7 +22,7 @@ public class TimerRoute extends RouteBuilder { @Override public void configure() throws Exception { - from("timer:foo?period=1s") + from("timer:foo?period=1000") .log("Hello World"); } } diff --git a/extensions-core/core-cloud/runtime/src/main/java/org/apache/camel/core/cloud/graal/SubstituteCachingServiceDiscovery.java b/extensions-core/core-cloud/runtime/src/main/java/org/apache/camel/core/cloud/graal/SubstituteCachingServiceDiscovery.java deleted file mode 100644 index 988b4d3..0000000 --- a/extensions-core/core-cloud/runtime/src/main/java/org/apache/camel/core/cloud/graal/SubstituteCachingServiceDiscovery.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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.core.cloud.graal; - -import java.util.List; -import java.util.concurrent.Executor; -import java.util.concurrent.ForkJoinPool; -import java.util.concurrent.TimeUnit; - -import com.github.benmanes.caffeine.cache.Caffeine; -import com.github.benmanes.caffeine.cache.LoadingCache; -import com.oracle.svm.core.annotate.Alias; -import com.oracle.svm.core.annotate.Substitute; -import com.oracle.svm.core.annotate.TargetClass; -import org.apache.camel.cloud.ServiceDefinition; -import org.apache.camel.cloud.ServiceDiscovery; -import org.apache.camel.impl.cloud.CachingServiceDiscovery; - -@TargetClass(CachingServiceDiscovery.class) -final class SubstituteCachingServiceDiscovery { - @Alias - private ServiceDiscovery delegate; - @Alias - private LoadingCache<String, List<ServiceDefinition>> cache; - @Alias - private long timeout; - - @Substitute - public void setTimeout(long timeout) { - this.timeout = timeout; - this.cache = Caffeine.newBuilder() - .executor(new Executor() { - @Override - public void execute(Runnable command) { - // workaround for https://github.com/quarkusio/quarkus/issues/3300 - ForkJoinPool.commonPool().execute(command); - } - }) - .expireAfterAccess(timeout, TimeUnit.MILLISECONDS) - .build(delegate::getServices); - } -} diff --git a/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/BuildProcessor.java b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/BuildProcessor.java index 7595070..485d510 100644 --- a/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/BuildProcessor.java +++ b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/BuildProcessor.java @@ -61,6 +61,7 @@ import org.apache.camel.quarkus.core.deployment.util.PathFilter; import org.apache.camel.quarkus.support.common.CamelCapabilities; import org.apache.camel.spi.TypeConverterLoader; import org.apache.camel.spi.TypeConverterRegistry; +import org.apache.camel.spi.XMLRoutesDefinitionLoader; import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; import org.jboss.jandex.IndexView; @@ -156,6 +157,11 @@ class BuildProcessor { "META-INF/services/org/apache/camel/language/*", "META-INF/services/org/apache/camel/dataformat/*", "META-INF/services/org/apache/camel/cron/*")); + + services.produce(new CamelServicePatternBuildItem( + CamelServiceDestination.DISCOVERY, + false, + "META-INF/services/org/apache/camel/" + XMLRoutesDefinitionLoader.FACTORY)); } @BuildStep @@ -384,13 +390,21 @@ class BuildProcessor { @Record(ExecutionTime.RUNTIME_INIT) @BuildStep - CamelRuntimeRegistryBuildItem bindRuntimeBeansToRegistry( + CamelRuntimeRegistryBuildItem bindRuntimeBeansToRegistryStatic( CamelRecorder recorder, RecorderContext recorderContext, ContainerBeansBuildItem containerBeans, CamelRegistryBuildItem registry, List<CamelRuntimeBeanBuildItem> registryItems) { + return doBindRuntimeBeansToRegistry(recorder, recorderContext, containerBeans, registry, registryItems); + } + CamelRuntimeRegistryBuildItem doBindRuntimeBeansToRegistry( + CamelRecorder recorder, + RecorderContext recorderContext, + ContainerBeansBuildItem containerBeans, + CamelRegistryBuildItem registry, + List<CamelRuntimeBeanBuildItem> registryItems) { registryItems.stream() .filter(item -> !containerBeans.getBeans().contains(item)) .forEach(item -> { @@ -502,7 +516,7 @@ class BuildProcessor { } @Overridable - @Record(value = ExecutionTime.RUNTIME_INIT, optional = true) + @Record(value = ExecutionTime.STATIC_INIT, optional = true) @BuildStep(onlyIf = Flags.MainEnabled.class) CamelReactiveExecutorBuildItem reactiveExecutor(CamelMainRecorder recorder) { return new CamelReactiveExecutorBuildItem(recorder.createReactiveExecutor()); @@ -519,6 +533,7 @@ class BuildProcessor { @Record(ExecutionTime.STATIC_INIT) @BuildStep(onlyIf = Flags.MainEnabled.class) CamelMainBuildItem main( + CamelConfig camelConfig, ContainerBeansBuildItem containerBeans, CamelMainRecorder recorder, CamelContextBuildItem context, @@ -528,6 +543,7 @@ class BuildProcessor { BeanContainerBuildItem beanContainer) { RuntimeValue<CamelMain> main = recorder.createCamelMain( + camelConfig, context.getCamelContext(), routesCollector.getValue(), beanContainer.getValue()); @@ -555,6 +571,35 @@ class BuildProcessor { * placeholder to * ensure the {@link org.apache.camel.spi.Registry} is fully configured before starting camel-main. * @param executor the {@link org.apache.camel.spi.ReactiveExecutor} to be configured on camel-main, this + * happens during {@link ExecutionTime#STATIC_INIT} because the executor may need to start + * threads and so on. + * @param shutdown a reference to a {@link io.quarkus.runtime.ShutdownContext} used to register shutdown logic. + * @param startList a placeholder to ensure camel-main start after the ArC container is fully initialized. This + * is required as under the hoods the camel registry may look-up beans form the + * container thus we need it to be fully initialized to avoid unexpected behaviors. + */ + @Record(ExecutionTime.STATIC_INIT) + @BuildStep(onlyIf = { Flags.MainEnabled.class }) + void startInit( + CamelMainRecorder recorder, + CamelMainBuildItem main, + CamelRuntimeRegistryBuildItem registry, + CamelReactiveExecutorBuildItem executor, + ShutdownContextBuildItem shutdown, + List<ServiceStartBuildItem> startList) { + + recorder.init(shutdown, main.getInstance(), executor.getInstance()); + } + + /** + * This method is responsible to start camel-main ar runtime. + * + * @param recorder the recorder. + * @param main a reference to a {@link CamelMain}. + * @param registry a reference to a {@link org.apache.camel.spi.Registry}; note that this parameter is here as + * placeholder to + * ensure the {@link org.apache.camel.spi.Registry} is fully configured before starting camel-main. + * @param executor the {@link org.apache.camel.spi.ReactiveExecutor} to be configured on camel-main, this * happens during {@link ExecutionTime#RUNTIME_INIT} because the executor may need to start * threads and so on. * @param shutdown a reference to a {@link io.quarkus.runtime.ShutdownContext} used to register shutdown logic. @@ -572,9 +617,9 @@ class BuildProcessor { ShutdownContextBuildItem shutdown, List<ServiceStartBuildItem> startList) { - recorder.setReactiveExecutor(main.getInstance(), executor.getInstance()); - recorder.start(shutdown, main.getInstance()); + recorder.start(main.getInstance()); } + } /** diff --git a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/BaseModel.java b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/BaseModel.java deleted file mode 100644 index 0a11942..0000000 --- a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/BaseModel.java +++ /dev/null @@ -1,364 +0,0 @@ -/* - * 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; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Function; - -import org.apache.camel.CamelContext; -import org.apache.camel.ExtendedCamelContext; -import org.apache.camel.FailedToStartRouteException; -import org.apache.camel.model.DataFormatDefinition; -import org.apache.camel.model.HystrixConfigurationDefinition; -import org.apache.camel.model.Model; -import org.apache.camel.model.ProcessorDefinition; -import org.apache.camel.model.ProcessorDefinitionHelper; -import org.apache.camel.model.Resilience4jConfigurationDefinition; -import org.apache.camel.model.RouteDefinition; -import org.apache.camel.model.RouteDefinitionHelper; -import org.apache.camel.model.RouteFilters; -import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition; -import org.apache.camel.model.rest.RestDefinition; -import org.apache.camel.model.transformer.TransformerDefinition; -import org.apache.camel.model.validator.ValidatorDefinition; - -public abstract class BaseModel implements Model { - - private final CamelContext camelContext; - - private final List<RouteDefinition> routeDefinitions = new ArrayList<>(); - private final List<RestDefinition> restDefinitions = new ArrayList<>(); - private Map<String, DataFormatDefinition> dataFormats = new HashMap<>(); - private List<TransformerDefinition> transformers = new ArrayList<>(); - private List<ValidatorDefinition> validators = new ArrayList<>(); - private Map<String, ServiceCallConfigurationDefinition> serviceCallConfigurations = new ConcurrentHashMap<>(); - private Map<String, HystrixConfigurationDefinition> hystrixConfigurations = new ConcurrentHashMap<>(); - private Map<String, Resilience4jConfigurationDefinition> resilience4jConfigurations = new ConcurrentHashMap<>(); - private Function<RouteDefinition, Boolean> routeFilter; - - public BaseModel(CamelContext camelContext) { - this.camelContext = camelContext; - } - - public CamelContext getCamelContext() { - return camelContext; - } - - @Override - public synchronized void addRouteDefinitions(Collection<RouteDefinition> routeDefinitions) throws Exception { - if (routeDefinitions == null || routeDefinitions.isEmpty()) { - return; - } - List<RouteDefinition> list = new ArrayList<>(); - routeDefinitions.forEach(r -> { - if (routeFilter == null || routeFilter.apply(r)) { - list.add(r); - } - }); - - removeRouteDefinitions(list); - this.routeDefinitions.addAll(list); - if (shouldStartRoutes()) { - startRouteDefinitions(list); - } - } - - @Override - public void addRouteDefinition(RouteDefinition routeDefinition) throws Exception { - addRouteDefinitions(Collections.singletonList(routeDefinition)); - } - - @Override - public synchronized void removeRouteDefinitions(Collection<RouteDefinition> routeDefinitions) throws Exception { - for (RouteDefinition routeDefinition : routeDefinitions) { - removeRouteDefinition(routeDefinition); - } - } - - @Override - public synchronized void removeRouteDefinition(RouteDefinition routeDefinition) throws Exception { - RouteDefinition toBeRemoved = routeDefinition; - String id = routeDefinition.getId(); - if (id != null) { - // remove existing route - camelContext.getRouteController().stopRoute(id); - camelContext.removeRoute(id); - toBeRemoved = getRouteDefinition(id); - } - this.routeDefinitions.remove(toBeRemoved); - } - - @Override - public synchronized List<RouteDefinition> getRouteDefinitions() { - return routeDefinitions; - } - - @Override - public synchronized RouteDefinition getRouteDefinition(String id) { - for (RouteDefinition route : routeDefinitions) { - if (route.idOrCreate(camelContext.adapt(ExtendedCamelContext.class).getNodeIdFactory()).equals(id)) { - return route; - } - } - return null; - } - - @Override - public synchronized List<RestDefinition> getRestDefinitions() { - return restDefinitions; - } - - @Override - public synchronized void addRestDefinitions(Collection<RestDefinition> restDefinitions, boolean addToRoutes) - throws Exception { - if (restDefinitions == null || restDefinitions.isEmpty()) { - return; - } - - this.restDefinitions.addAll(restDefinitions); - if (addToRoutes) { - // rests are also routes so need to add them there too - for (final RestDefinition restDefinition : restDefinitions) { - List<RouteDefinition> routeDefinitions = restDefinition.asRouteDefinition(camelContext); - addRouteDefinitions(routeDefinitions); - } - } - } - - @Override - public ServiceCallConfigurationDefinition getServiceCallConfiguration(String serviceName) { - if (serviceName == null) { - serviceName = ""; - } - - return serviceCallConfigurations.get(serviceName); - } - - @Override - public void setServiceCallConfiguration(ServiceCallConfigurationDefinition configuration) { - serviceCallConfigurations.put("", configuration); - } - - @Override - public void setServiceCallConfigurations(List<ServiceCallConfigurationDefinition> configurations) { - if (configurations != null) { - for (ServiceCallConfigurationDefinition configuration : configurations) { - serviceCallConfigurations.put(configuration.getId(), configuration); - } - } - } - - @Override - public void addServiceCallConfiguration(String serviceName, ServiceCallConfigurationDefinition configuration) { - serviceCallConfigurations.put(serviceName, configuration); - } - - @Override - public HystrixConfigurationDefinition getHystrixConfiguration(String id) { - if (id == null) { - id = ""; - } - - return hystrixConfigurations.get(id); - } - - @Override - public void setHystrixConfiguration(HystrixConfigurationDefinition configuration) { - hystrixConfigurations.put("", configuration); - } - - @Override - public void setHystrixConfigurations(List<HystrixConfigurationDefinition> configurations) { - if (configurations != null) { - for (HystrixConfigurationDefinition configuration : configurations) { - hystrixConfigurations.put(configuration.getId(), configuration); - } - } - } - - @Override - public void addHystrixConfiguration(String id, HystrixConfigurationDefinition configuration) { - hystrixConfigurations.put(id, configuration); - } - - @Override - public Resilience4jConfigurationDefinition getResilience4jConfiguration(String id) { - if (id == null) { - id = ""; - } - - return resilience4jConfigurations.get(id); - } - - @Override - public void setResilience4jConfiguration(Resilience4jConfigurationDefinition configuration) { - resilience4jConfigurations.put("", configuration); - } - - @Override - public void setResilience4jConfigurations(List<Resilience4jConfigurationDefinition> configurations) { - if (configurations != null) { - for (Resilience4jConfigurationDefinition configuration : configurations) { - resilience4jConfigurations.put(configuration.getId(), configuration); - } - } - } - - @Override - public void addResilience4jConfiguration(String id, Resilience4jConfigurationDefinition configuration) { - resilience4jConfigurations.put(id, configuration); - } - - @Override - public DataFormatDefinition resolveDataFormatDefinition(String name) { - // lookup type and create the data format from it - DataFormatDefinition type = lookup(camelContext, name, DataFormatDefinition.class); - if (type == null && getDataFormats() != null) { - type = getDataFormats().get(name); - } - return type; - } - - @Override - public ProcessorDefinition getProcessorDefinition(String id) { - for (RouteDefinition route : getRouteDefinitions()) { - Iterator<ProcessorDefinition> it = ProcessorDefinitionHelper.filterTypeInOutputs(route.getOutputs(), - ProcessorDefinition.class); - while (it.hasNext()) { - ProcessorDefinition proc = it.next(); - if (id.equals(proc.getId())) { - return proc; - } - } - } - return null; - } - - @Override - public <T extends ProcessorDefinition> T getProcessorDefinition(String id, Class<T> type) { - ProcessorDefinition answer = getProcessorDefinition(id); - if (answer != null) { - return type.cast(answer); - } - return null; - } - - @Override - public void setDataFormats(Map<String, DataFormatDefinition> dataFormats) { - this.dataFormats = dataFormats; - } - - @Override - public Map<String, DataFormatDefinition> getDataFormats() { - return dataFormats; - } - - @Override - public void setTransformers(List<TransformerDefinition> transformers) { - this.transformers = transformers; - } - - @Override - public List<TransformerDefinition> getTransformers() { - return transformers; - } - - @Override - public void setValidators(List<ValidatorDefinition> validators) { - this.validators = validators; - } - - @Override - public List<ValidatorDefinition> getValidators() { - return validators; - } - - @Override - public void startRouteDefinitions() throws Exception { - startRouteDefinitions(routeDefinitions); - } - - @Override - public void setRouteFilterPattern(String include, String exclude) { - setRouteFilter(RouteFilters.filterByPattern(include, exclude)); - } - - @Override - public Function<RouteDefinition, Boolean> getRouteFilter() { - return routeFilter; - } - - @Override - public void setRouteFilter(Function<RouteDefinition, Boolean> routeFilter) { - this.routeFilter = routeFilter; - } - - protected void startRouteDefinitions(Collection<RouteDefinition> list) throws Exception { - if (list != null) { - for (RouteDefinition route : list) { - startRoute(route); - } - } - } - - public void startRoute(RouteDefinition routeDefinition) throws Exception { - prepare(routeDefinition); - start(routeDefinition); - } - - protected void prepare(RouteDefinition routeDefinition) throws Exception { - // assign ids to the routes and validate that the id's is all unique - RouteDefinitionHelper.forceAssignIds(camelContext, routeDefinitions); - String duplicate = RouteDefinitionHelper.validateUniqueIds(routeDefinition, routeDefinitions); - if (duplicate != null) { - throw new FailedToStartRouteException(routeDefinition.getId(), - "duplicate id detected: " + duplicate + ". Please correct ids to be unique among all your routes."); - } - - // must ensure route is prepared, before we can start it - if (!routeDefinition.isPrepared()) { - RouteDefinitionHelper.prepareRoute(camelContext, routeDefinition); - routeDefinition.markPrepared(); - } - } - - protected abstract void start(RouteDefinition routeDefinition) throws Exception; - - /** - * Should we start newly added routes? - */ - protected boolean shouldStartRoutes() { - return camelContext.isStarted() && !camelContext.isStarting(); - } - - protected static <T> T lookup(CamelContext context, String ref, Class<T> type) { - try { - return context.getRegistry().lookupByNameAndType(ref, type); - } catch (Exception e) { - // need to ignore not same type and return it as null - return null; - } - } - -} diff --git a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelConfig.java b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelConfig.java index b8fa70b..70de1b1 100644 --- a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelConfig.java +++ b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelConfig.java @@ -63,6 +63,13 @@ public class CamelConfig { public boolean enabled; /** + * If {@code true}, the camel context will be started at initialization time + * to boot up faster. + */ + @ConfigItem + public boolean lightweight; + + /** * Build time configuration options for routes discovery. */ @ConfigItem diff --git a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelMain.java b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelMain.java index 98691cf..f5d90ad 100644 --- a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelMain.java +++ b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelMain.java @@ -19,11 +19,7 @@ package org.apache.camel.quarkus.core; import java.util.Collection; import java.util.Collections; -import org.apache.camel.CamelContext; -import org.apache.camel.CamelContextAware; -import org.apache.camel.ExtendedCamelContext; -import org.apache.camel.ProducerTemplate; -import org.apache.camel.RoutesBuilder; +import org.apache.camel.*; import org.apache.camel.main.BaseMainSupport; import org.apache.camel.main.MainConfigurationProperties; import org.apache.camel.main.MainListener; @@ -35,30 +31,44 @@ import org.slf4j.LoggerFactory; public class CamelMain extends BaseMainSupport implements CamelContextAware { private static final Logger LOGGER = LoggerFactory.getLogger(CamelMain.class); + public CamelMain() { + } + @Override public void setCamelContext(CamelContext camelContext) { this.camelContext = camelContext; } @Override + protected void doInit() throws Exception { + super.doInit(); + postProcessCamelContext(camelContext); + camelContext.init(); + } + + @Override protected void doStart() throws Exception { for (MainListener listener : listeners) { listener.beforeStart(this); } - postProcessCamelContext(getCamelContext()); getCamelContext().start(); for (MainListener listener : listeners) { listener.afterStart(this); } + + if (getMainConfigurationProperties().isLightweight()) { + routesCollector = null; + routeBuilders = null; + } } @Override protected void postProcessCamelContext(CamelContext camelContext) throws Exception { super.postProcessCamelContext(camelContext); - // post process classes with camel's post processor so classes have supot + // post process classes with camel's post processor so classes have support // for camel's simple di CamelBeanPostProcessor postProcessor = camelContext.adapt(ExtendedCamelContext.class).getBeanPostProcessor(); for (RoutesBuilder builder : getRoutesBuilders()) { diff --git a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelMainRecorder.java b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelMainRecorder.java index ec0d238..dacdf4f 100644 --- a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelMainRecorder.java +++ b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelMainRecorder.java @@ -36,10 +36,12 @@ public class CamelMainRecorder { } public RuntimeValue<CamelMain> createCamelMain( + CamelConfig camelConfig, RuntimeValue<CamelContext> runtime, RuntimeValue<RoutesCollector> routesCollector, BeanContainer container) { CamelMain main = new CamelMain(); + main.getMainConfigurationProperties().setLightweight(camelConfig.main.lightweight); main.setRoutesCollector(routesCollector.getValue()); main.setCamelContext(runtime.getValue()); main.addMainListener(new CamelMainEventDispatcher()); @@ -76,11 +78,7 @@ public class CamelMainRecorder { main.getValue().addMainListener(listener.getValue()); } - public void setReactiveExecutor(RuntimeValue<CamelMain> main, RuntimeValue<ReactiveExecutor> executor) { - main.getValue().getCamelContext().adapt(ExtendedCamelContext.class).setReactiveExecutor(executor.getValue()); - } - - public void start(ShutdownContext shutdown, RuntimeValue<CamelMain> main) { + public void init(ShutdownContext shutdown, RuntimeValue<CamelMain> main, RuntimeValue<ReactiveExecutor> executor) { shutdown.addShutdownTask(new Runnable() { @Override public void run() { @@ -91,9 +89,12 @@ public class CamelMainRecorder { } } }); + main.getValue().getCamelContext().adapt(ExtendedCamelContext.class).setReactiveExecutor(executor.getValue()); + main.getValue().init(); + } + public void start(RuntimeValue<CamelMain> main) { try { - main.getValue().init(); main.getValue().start(); } catch (Exception e) { throw new RuntimeException(e); diff --git a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelRecorder.java b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelRecorder.java index 35e5688..c146d33 100644 --- a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelRecorder.java +++ b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelRecorder.java @@ -20,7 +20,7 @@ import io.quarkus.arc.runtime.BeanContainer; import io.quarkus.runtime.RuntimeValue; import io.quarkus.runtime.annotations.Recorder; import org.apache.camel.CamelContext; -import org.apache.camel.catalog.RuntimeCamelCatalog; +import org.apache.camel.impl.lw.LightweightCamelContext; import org.apache.camel.model.ValidateDefinition; import org.apache.camel.model.validator.PredicateValidatorDefinition; import org.apache.camel.quarkus.core.FastFactoryFinderResolver.Builder; @@ -69,23 +69,43 @@ public class CamelRecorder { String version, CamelConfig config) { - FastCamelContext context = new FastCamelContext( - factoryFinderResolver.getValue(), - version, - xmlLoader.getValue(), - xmlModelDumper.getValue()); - - context.setDefaultExtension(RuntimeCamelCatalog.class, () -> new CamelRuntimeCatalog(config.runtimeCatalog)); - context.setRegistry(registry.getValue()); - context.setTypeConverterRegistry(typeConverterRegistry.getValue()); - context.setLoadTypeConverters(false); - context.setModelJAXBContextFactory(contextFactory.getValue()); - context.init(); - - // register to the container - beanContainer.instance(CamelProducers.class).setContext(context); + if (config.main.lightweight) { + FastLightweightCamelContext context = new FastLightweightCamelContext( + factoryFinderResolver.getValue(), + version, + xmlLoader.getValue(), + xmlModelDumper.getValue()); + context.setRuntimeCamelCatalog(new CamelRuntimeCatalog(config.runtimeCatalog)); + context.setRegistry(registry.getValue()); + context.setTypeConverterRegistry(typeConverterRegistry.getValue()); + context.setLoadTypeConverters(false); + context.setModelJAXBContextFactory(contextFactory.getValue()); + context.build(); + + // register to the container + beanContainer.instance(CamelProducers.class).setContext(context); + + return new RuntimeValue<>(context); + } else { + FastCamelContext context = new FastCamelContext( + null, + factoryFinderResolver.getValue(), + version, + xmlLoader.getValue(), + xmlModelDumper.getValue()); + context.setRuntimeCamelCatalog(new CamelRuntimeCatalog(config.runtimeCatalog)); + context.setRegistry(registry.getValue()); + context.setTypeConverterRegistry(typeConverterRegistry.getValue()); + context.setLoadTypeConverters(false); + context.setModelJAXBContextFactory(contextFactory.getValue()); + context.build(); + + // register to the container + beanContainer.instance(CamelProducers.class).setContext(context); + + return new RuntimeValue<>(context); + } - return new RuntimeValue<>(context); } public void bind( @@ -150,4 +170,33 @@ public class CamelRecorder { public RuntimeValue<FactoryFinderResolver> factoryFinderResolver(RuntimeValue<Builder> builder) { return new RuntimeValue<>(builder.getValue().build()); } + + public static class FastLightweightCamelContext extends LightweightCamelContext { + public FastLightweightCamelContext(FactoryFinderResolver factoryFinderResolver, String version, + XMLRoutesDefinitionLoader xmlLoader, ModelToXMLDumper modelDumper) { + super((CamelContext) null); + delegate = new FastCamelContextWithRef(FastLightweightCamelContext.this, + factoryFinderResolver, version, + xmlLoader, modelDumper); + } + + public void init() { + // new Exception().printStackTrace(); + super.init(); + } + + static class FastCamelContextWithRef extends FastCamelContext { + public FastCamelContextWithRef(CamelContext reference, FactoryFinderResolver factoryFinderResolver, String version, + XMLRoutesDefinitionLoader xmlLoader, ModelToXMLDumper modelDumper) { + super(reference, factoryFinderResolver, version, xmlLoader, modelDumper); + disableJMX(); + } + + public void init() { + // new Exception().printStackTrace(); + super.init(); + } + + } + } } diff --git a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelRoutesCollector.java b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelRoutesCollector.java index 0c63b2a..e4329cb 100644 --- a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelRoutesCollector.java +++ b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelRoutesCollector.java @@ -18,6 +18,7 @@ package org.apache.camel.quarkus.core; import java.io.FileNotFoundException; import java.io.InputStream; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; @@ -69,12 +70,16 @@ public class CamelRoutesCollector implements RoutesCollector { for (String part : directory.split(",")) { LOGGER.info("Loading additional Camel XML routes from: {}", part); try { + LOGGER.info("Resolving from current dir: {}", Paths.get(".").toAbsolutePath().toString()); + int res = 0; for (InputStream is : resolver.findResources(part)) { + res++; Object definition = xmlRoutesLoader.loadRoutesDefinition(camelContext, is); if (definition instanceof RoutesDefinition) { answer.add((RoutesDefinition) definition); } } + LOGGER.info("Found {} resources", res); } catch (FileNotFoundException e) { LOGGER.debug("No XML routes found in {}. Skipping XML routes detection.", part); } catch (Exception e) { diff --git a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/DisabledValidateReifier.java b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/DisabledValidateReifier.java index 911bfe7..a9b8144 100644 --- a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/DisabledValidateReifier.java +++ b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/DisabledValidateReifier.java @@ -17,15 +17,15 @@ package org.apache.camel.quarkus.core; import org.apache.camel.Processor; +import org.apache.camel.Route; import org.apache.camel.model.ProcessorDefinition; import org.apache.camel.model.ValidateDefinition; import org.apache.camel.reifier.ProcessorReifier; -import org.apache.camel.spi.RouteContext; public class DisabledValidateReifier extends ProcessorReifier<ValidateDefinition> { - public DisabledValidateReifier(RouteContext routeContext, ProcessorDefinition<?> definition) { - super(routeContext, (ValidateDefinition) definition); + public DisabledValidateReifier(Route route, ProcessorDefinition<?> definition) { + super(route, (ValidateDefinition) definition); } @Override diff --git a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastCamelContext.java b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastCamelContext.java index f0d0493..2cb59d4 100644 --- a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastCamelContext.java +++ b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastCamelContext.java @@ -19,34 +19,32 @@ package org.apache.camel.quarkus.core; import java.io.IOException; import java.io.InputStream; import java.util.Collection; +import java.util.Date; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.function.Function; -import org.apache.camel.AsyncProcessor; -import org.apache.camel.CatalogCamelContext; -import org.apache.camel.Component; -import org.apache.camel.Endpoint; -import org.apache.camel.Processor; -import org.apache.camel.TypeConverter; +import org.apache.camel.*; +import org.apache.camel.builder.AdviceWithRouteBuilder; import org.apache.camel.catalog.RuntimeCamelCatalog; import org.apache.camel.catalog.impl.DefaultRuntimeCamelCatalog; import org.apache.camel.component.microprofile.config.CamelMicroProfilePropertiesSource; import org.apache.camel.health.HealthCheckRegistry; import org.apache.camel.impl.DefaultExecutorServiceManager; import org.apache.camel.impl.engine.AbstractCamelContext; -import org.apache.camel.impl.engine.BeanProcessorFactoryResolver; -import org.apache.camel.impl.engine.BeanProxyFactoryResolver; +import org.apache.camel.impl.engine.BaseServiceResolver; import org.apache.camel.impl.engine.DefaultAsyncProcessorAwaitManager; import org.apache.camel.impl.engine.DefaultBeanIntrospection; import org.apache.camel.impl.engine.DefaultCamelBeanPostProcessor; import org.apache.camel.impl.engine.DefaultCamelContextNameStrategy; import org.apache.camel.impl.engine.DefaultClassResolver; +import org.apache.camel.impl.engine.DefaultComponentNameResolver; import org.apache.camel.impl.engine.DefaultComponentResolver; import org.apache.camel.impl.engine.DefaultConfigurerResolver; import org.apache.camel.impl.engine.DefaultDataFormatResolver; import org.apache.camel.impl.engine.DefaultEndpointRegistry; +import org.apache.camel.impl.engine.DefaultHeadersMapFactory; import org.apache.camel.impl.engine.DefaultInflightRepository; import org.apache.camel.impl.engine.DefaultInjector; import org.apache.camel.impl.engine.DefaultLanguageResolver; @@ -55,7 +53,6 @@ import org.apache.camel.impl.engine.DefaultNodeIdFactory; import org.apache.camel.impl.engine.DefaultPackageScanClassResolver; import org.apache.camel.impl.engine.DefaultPackageScanResourceResolver; import org.apache.camel.impl.engine.DefaultProcessorFactory; -import org.apache.camel.impl.engine.DefaultReactiveExecutor; import org.apache.camel.impl.engine.DefaultRouteController; import org.apache.camel.impl.engine.DefaultStreamCachingStrategy; import org.apache.camel.impl.engine.DefaultTracer; @@ -63,8 +60,7 @@ import org.apache.camel.impl.engine.DefaultTransformerRegistry; import org.apache.camel.impl.engine.DefaultUnitOfWorkFactory; import org.apache.camel.impl.engine.DefaultValidatorRegistry; import org.apache.camel.impl.engine.EndpointKey; -import org.apache.camel.impl.engine.HeadersMapFactoryResolver; -import org.apache.camel.impl.engine.RestRegistryFactoryResolver; +import org.apache.camel.impl.engine.RouteService; import org.apache.camel.impl.health.DefaultHealthCheckRegistry; import org.apache.camel.impl.transformer.TransformerKey; import org.apache.camel.impl.validator.ValidatorKey; @@ -75,69 +71,46 @@ import org.apache.camel.model.ModelCamelContext; import org.apache.camel.model.ProcessorDefinition; import org.apache.camel.model.Resilience4jConfigurationDefinition; import org.apache.camel.model.RouteDefinition; +import org.apache.camel.model.RouteDefinitionHelper; import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition; +import org.apache.camel.model.language.ExpressionDefinition; import org.apache.camel.model.rest.RestDefinition; import org.apache.camel.model.transformer.TransformerDefinition; import org.apache.camel.model.validator.ValidatorDefinition; import org.apache.camel.processor.MulticastProcessor; -import org.apache.camel.spi.AsyncProcessorAwaitManager; -import org.apache.camel.spi.BeanIntrospection; -import org.apache.camel.spi.BeanProcessorFactory; -import org.apache.camel.spi.BeanProxyFactory; -import org.apache.camel.spi.CamelBeanPostProcessor; -import org.apache.camel.spi.CamelContextNameStrategy; -import org.apache.camel.spi.ClassResolver; -import org.apache.camel.spi.ComponentResolver; -import org.apache.camel.spi.ConfigurerResolver; -import org.apache.camel.spi.DataFormat; -import org.apache.camel.spi.DataFormatResolver; -import org.apache.camel.spi.EndpointRegistry; -import org.apache.camel.spi.ExecutorServiceManager; -import org.apache.camel.spi.FactoryFinderResolver; -import org.apache.camel.spi.HeadersMapFactory; -import org.apache.camel.spi.InflightRepository; -import org.apache.camel.spi.Injector; -import org.apache.camel.spi.Language; -import org.apache.camel.spi.LanguageResolver; -import org.apache.camel.spi.ManagementNameStrategy; -import org.apache.camel.spi.MessageHistoryFactory; -import org.apache.camel.spi.ModelJAXBContextFactory; -import org.apache.camel.spi.ModelToXMLDumper; -import org.apache.camel.spi.NodeIdFactory; -import org.apache.camel.spi.PackageScanClassResolver; -import org.apache.camel.spi.PackageScanResourceResolver; -import org.apache.camel.spi.ProcessorFactory; -import org.apache.camel.spi.PropertiesComponent; -import org.apache.camel.spi.ReactiveExecutor; -import org.apache.camel.spi.Registry; -import org.apache.camel.spi.RestRegistryFactory; -import org.apache.camel.spi.RouteController; -import org.apache.camel.spi.ShutdownStrategy; -import org.apache.camel.spi.StreamCachingStrategy; -import org.apache.camel.spi.Tracer; -import org.apache.camel.spi.TransformerRegistry; -import org.apache.camel.spi.TypeConverterRegistry; -import org.apache.camel.spi.UnitOfWorkFactory; -import org.apache.camel.spi.UuidGenerator; -import org.apache.camel.spi.ValidatorRegistry; -import org.apache.camel.spi.XMLRoutesDefinitionLoader; +import org.apache.camel.reifier.RouteReifier; +import org.apache.camel.reifier.errorhandler.ErrorHandlerReifier; +import org.apache.camel.reifier.language.ExpressionReifier; +import org.apache.camel.reifier.transformer.TransformerReifier; +import org.apache.camel.reifier.validator.ValidatorReifier; +import org.apache.camel.spi.*; import org.apache.camel.support.CamelContextHelper; import org.apache.camel.util.IOHelper; +import org.apache.camel.util.ObjectHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -public class FastCamelContext extends AbstractCamelContext implements CatalogCamelContext, ModelCamelContext { - private final Model model; +public class FastCamelContext extends AbstractCamelContext implements ModelCamelContext { + + private static final Logger LOG = LoggerFactory.getLogger(FastCamelContext.class); + + private final CamelContext reference; private final String version; - private final XMLRoutesDefinitionLoader xmlLoader; - private final ModelToXMLDumper modelDumper; + private XMLRoutesDefinitionLoader xmlLoader; + private ModelToXMLDumper modelDumper; + private Model model; + private Date startDate; - public FastCamelContext(FactoryFinderResolver factoryFinderResolver, String version, XMLRoutesDefinitionLoader xmlLoader, + public FastCamelContext(CamelContext reference, FactoryFinderResolver factoryFinderResolver, String version, + XMLRoutesDefinitionLoader xmlLoader, ModelToXMLDumper modelDumper) { super(false); - + this.reference = reference != null ? reference : this; this.version = version; this.xmlLoader = xmlLoader; this.modelDumper = modelDumper; - this.model = new FastModel(this); + + this.model = new FastModel(getCamelContextReference()); setFactoryFinderResolver(factoryFinderResolver); setTracing(Boolean.FALSE); @@ -145,6 +118,57 @@ public class FastCamelContext extends AbstractCamelContext implements CatalogCam setMessageHistory(Boolean.FALSE); setDefaultExtension(HealthCheckRegistry.class, DefaultHealthCheckRegistry::new); + LOG.info("Creating Apache Camel {} (CamelContext: {})", getVersion(), getName()); + } + + @Override + public CamelContext getCamelContextReference() { + return reference; + } + + @Override + public long getUptimeMillis() { + if (startDate == null) { + return 0; + } + return new Date().getTime() - startDate.getTime(); + } + + @Override + public Date getStartDate() { + return startDate; + } + + @Override + public void startRouteDefinitions() throws Exception { + List<RouteDefinition> routeDefinitions = model.getRouteDefinitions(); + if (routeDefinitions != null) { + startRouteDefinitions(routeDefinitions); + } + } + + public void startRouteDefinitions(List<RouteDefinition> routeDefinitions) throws Exception { + RouteDefinitionHelper.forceAssignIds(getCamelContextReference(), routeDefinitions); + for (RouteDefinition routeDefinition : routeDefinitions) { + // assign ids to the routes and validate that the id's is all unique + String duplicate = RouteDefinitionHelper.validateUniqueIds(routeDefinition, routeDefinitions); + if (duplicate != null) { + throw new FailedToStartRouteException(routeDefinition.getId(), + "duplicate id detected: " + duplicate + ". Please correct ids to be unique among all your routes."); + } + + // must ensure route is prepared, before we can start it + if (!routeDefinition.isPrepared()) { + RouteDefinitionHelper.prepareRoute(getCamelContextReference(), routeDefinition); + routeDefinition.markPrepared(); + } + + // indicate we are staring the route using this thread so + // we are able to query this if needed + Route route = new RouteReifier(getCamelContextReference(), routeDefinition).createRoute(); + RouteService routeService = new RouteService(route); + routeService.warmUp(); + } } @Override @@ -209,13 +233,18 @@ public class FastCamelContext extends AbstractCamelContext implements CatalogCam } @Override + protected HealthCheckRegistry createHealthCheckRegistry() { + return new DefaultHealthCheckRegistry(getCamelContextReference()); + } + + @Override protected Injector createInjector() { - return new DefaultInjector(this); + return new DefaultInjector(getCamelContextReference()); } @Override protected CamelBeanPostProcessor createBeanPostProcessor() { - return new DefaultCamelBeanPostProcessor(this); + return new DefaultCamelBeanPostProcessor(getCamelContextReference()); } @Override @@ -236,7 +265,7 @@ public class FastCamelContext extends AbstractCamelContext implements CatalogCam @Override protected ClassResolver createClassResolver() { - return new DefaultClassResolver(this); + return new DefaultClassResolver(getCamelContextReference()); } @Override @@ -261,7 +290,7 @@ public class FastCamelContext extends AbstractCamelContext implements CatalogCam @Override protected RouteController createRouteController() { - return new DefaultRouteController(this); + return new DefaultRouteController(getCamelContextReference()); } @Override @@ -271,7 +300,7 @@ public class FastCamelContext extends AbstractCamelContext implements CatalogCam @Override protected ExecutorServiceManager createExecutorServiceManager() { - return new DefaultExecutorServiceManager(this); + return new DefaultExecutorServiceManager(getCamelContextReference()); } @Override @@ -285,17 +314,25 @@ public class FastCamelContext extends AbstractCamelContext implements CatalogCam @Override protected HeadersMapFactory createHeadersMapFactory() { - return new HeadersMapFactoryResolver().resolve(this); + return new BaseServiceResolver<>(HeadersMapFactory.FACTORY, HeadersMapFactory.class) + .resolve(getCamelContextReference()) + .orElseGet(DefaultHeadersMapFactory::new); } @Override protected BeanProxyFactory createBeanProxyFactory() { - return new BeanProxyFactoryResolver().resolve(this); + return new BaseServiceResolver<>(BeanProxyFactory.FACTORY, BeanProxyFactory.class) + .resolve(getCamelContextReference()) + .orElseThrow(() -> new IllegalArgumentException("Cannot find BeanProxyFactory on classpath. " + + "Add camel-bean to classpath.")); } @Override protected BeanProcessorFactory createBeanProcessorFactory() { - return new BeanProcessorFactoryResolver().resolve(this); + return new BaseServiceResolver<>(BeanProcessorFactory.FACTORY, BeanProcessorFactory.class) + .resolve(getCamelContextReference()) + .orElseThrow(() -> new IllegalArgumentException("Cannot find BeanProcessorFactory on classpath. " + + "Add camel-bean to classpath.")); } @Override @@ -308,9 +345,7 @@ public class FastCamelContext extends AbstractCamelContext implements CatalogCam org.apache.camel.component.properties.PropertiesComponent pc = new org.apache.camel.component.properties.PropertiesComponent(); pc.setAutoDiscoverPropertiesSources(false); pc.addPropertiesSource(new CamelMicroProfilePropertiesSource()); - return pc; - } @Override @@ -337,7 +372,7 @@ public class FastCamelContext extends AbstractCamelContext implements CatalogCam protected Tracer createTracer() { Tracer tracer = null; if (getRegistry() != null) { - Map<String, Tracer> map = this.getRegistry().findByTypeWithName(Tracer.class); + Map<String, Tracer> map = getRegistry().findByTypeWithName(Tracer.class); if (map.size() == 1) { tracer = map.values().iterator().next(); } @@ -357,12 +392,15 @@ public class FastCamelContext extends AbstractCamelContext implements CatalogCam @Override protected RestRegistryFactory createRestRegistryFactory() { - return new RestRegistryFactoryResolver().resolve(this); + return new BaseServiceResolver<>(RestRegistryFactory.FACTORY, RestRegistryFactory.class) + .resolve(getCamelContextReference()) + .orElseThrow(() -> new IllegalArgumentException("Cannot find RestRegistryFactory on classpath. " + + "Add camel-rest to classpath.")); } @Override protected EndpointRegistry<EndpointKey> createEndpointRegistry(Map<EndpointKey, Endpoint> endpoints) { - return new DefaultEndpointRegistry(this, endpoints); + return new DefaultEndpointRegistry(getCamelContextReference(), endpoints); } @Override @@ -372,23 +410,24 @@ public class FastCamelContext extends AbstractCamelContext implements CatalogCam @Override protected TransformerRegistry<TransformerKey> createTransformerRegistry() { - return new DefaultTransformerRegistry(this); + return new DefaultTransformerRegistry(getCamelContextReference()); } @Override protected ValidatorRegistry<ValidatorKey> createValidatorRegistry() { - return new DefaultValidatorRegistry(this); + return new DefaultValidatorRegistry(getCamelContextReference()); } @Override protected ReactiveExecutor createReactiveExecutor() { - return new DefaultReactiveExecutor(); + throw new UnsupportedOperationException(); } @Override public AsyncProcessor createMulticast(Collection<Processor> processors, ExecutorService executor, boolean shutdownExecutorService) { - return new MulticastProcessor(this, processors, null, true, executor, shutdownExecutorService, + return new MulticastProcessor(getCamelContextReference(), null, processors, null, true, executor, + shutdownExecutorService, false, false, 0L, null, false, false); } @@ -398,14 +437,33 @@ public class FastCamelContext extends AbstractCamelContext implements CatalogCam } @Override + protected ComponentNameResolver createComponentNameResolver() { + return new DefaultComponentNameResolver(); + } + + @Override + public Processor createErrorHandler(Route route, Processor processor) throws Exception { + return ErrorHandlerReifier.reifier(route, route.getErrorHandlerFactory()) + .createErrorHandler(processor); + } + + @Override + protected RestBindingJaxbDataFormatFactory createRestBindingJaxbDataFormatFactory() { + return new BaseServiceResolver<>(RestBindingJaxbDataFormatFactory.FACTORY, RestBindingJaxbDataFormatFactory.class) + .resolve(getCamelContextReference()) + .orElseThrow(() -> new IllegalArgumentException("Cannot find RestBindingJaxbDataFormatFactory on classpath. " + + "Add camel-jaxb to classpath.")); + } + + @Override public void setTypeConverterRegistry(TypeConverterRegistry typeConverterRegistry) { super.setTypeConverterRegistry(typeConverterRegistry); - - typeConverterRegistry.setCamelContext(this); + typeConverterRegistry.setCamelContext(getCamelContextReference()); } @Override public void doInit() throws Exception { + LOG.info("Apache Camel {} (CamelContext: {}) is initializing", getVersion(), getName()); super.doInit(); forceLazyInitialization(); @@ -446,7 +504,8 @@ public class FastCamelContext extends AbstractCamelContext implements CatalogCam if (instance != null) { clazz = instance.getClass(); } else { - clazz = getFactoryFinder(DefaultDataFormatResolver.DATAFORMAT_RESOURCE_PATH).findClass(dataFormatName).orElse(null); + clazz = getFactoryFinder(DefaultDataFormatResolver.DATAFORMAT_RESOURCE_PATH).findClass(dataFormatName) + .orElse(null); if (clazz == null) { return null; } @@ -511,11 +570,6 @@ public class FastCamelContext extends AbstractCamelContext implements CatalogCam // @Override - public void startRouteDefinitions() throws Exception { - model.startRouteDefinitions(); - } - - @Override public List<RouteDefinition> getRouteDefinitions() { return model.getRouteDefinitions(); } @@ -576,7 +630,7 @@ public class FastCamelContext extends AbstractCamelContext implements CatalogCam } @Override - public <T extends ProcessorDefinition> T getProcessorDefinition(String id, Class<T> type) { + public <T extends ProcessorDefinition<T>> T getProcessorDefinition(String id, Class<T> type) { return model.getProcessorDefinition(id, type); } @@ -674,4 +728,43 @@ public class FastCamelContext extends AbstractCamelContext implements CatalogCam public Function<RouteDefinition, Boolean> getRouteFilter() { return model.getRouteFilter(); } + + @Override + public Expression createExpression(ExpressionDefinition definition) { + return ExpressionReifier.reifier(this, definition).createExpression(); + } + + @Override + public Predicate createPredicate(ExpressionDefinition definition) { + return ExpressionReifier.reifier(this, definition).createPredicate(); + } + + @Override + public RouteDefinition adviceWith(RouteDefinition definition, AdviceWithRouteBuilder builder) throws Exception { + return RouteReifier.adviceWith(definition, this, builder); + } + + @Override + public void registerValidator(ValidatorDefinition def) { + model.getValidators().add(def); + Validator validator = ValidatorReifier.reifier(this, def).createValidator(); + getValidatorRegistry().put(createValidatorKey(def), validator); + } + + private static ValueHolder<String> createValidatorKey(ValidatorDefinition def) { + return new ValidatorKey(new DataType(def.getType())); + } + + @Override + public void registerTransformer(TransformerDefinition def) { + model.getTransformers().add(def); + Transformer transformer = TransformerReifier.reifier(this, def).createTransformer(); + getTransformerRegistry().put(createTransformerKey(def), transformer); + } + + private static ValueHolder<String> createTransformerKey(TransformerDefinition def) { + return ObjectHelper.isNotEmpty(def.getScheme()) ? new TransformerKey(def.getScheme()) + : new TransformerKey(new DataType(def.getFromType()), new DataType(def.getToType())); + } + } diff --git a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastModel.java b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastModel.java index 9be64bd..0718c43 100644 --- a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastModel.java +++ b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastModel.java @@ -17,209 +17,310 @@ package org.apache.camel.quarkus.core; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; import org.apache.camel.CamelContext; -import org.apache.camel.ErrorHandlerFactory; import org.apache.camel.ExtendedCamelContext; -import org.apache.camel.NamedNode; -import org.apache.camel.Navigate; -import org.apache.camel.Processor; -import org.apache.camel.Route; -import org.apache.camel.Service; -import org.apache.camel.impl.engine.AbstractCamelContext; -import org.apache.camel.impl.engine.BaseRouteService; -import org.apache.camel.impl.engine.DefaultRouteContext; -import org.apache.camel.model.OnCompletionDefinition; -import org.apache.camel.model.OnExceptionDefinition; +import org.apache.camel.model.DataFormatDefinition; +import org.apache.camel.model.HystrixConfigurationDefinition; +import org.apache.camel.model.Model; +import org.apache.camel.model.ModelCamelContext; import org.apache.camel.model.ProcessorDefinition; +import org.apache.camel.model.ProcessorDefinitionHelper; +import org.apache.camel.model.Resilience4jConfigurationDefinition; import org.apache.camel.model.RouteDefinition; -import org.apache.camel.model.RouteDefinitionHelper; -import org.apache.camel.processor.channel.DefaultChannel; -import org.apache.camel.reifier.RouteReifier; -import org.apache.camel.support.CamelContextHelper; +import org.apache.camel.model.RouteFilters; +import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition; +import org.apache.camel.model.rest.RestDefinition; +import org.apache.camel.model.transformer.TransformerDefinition; +import org.apache.camel.model.validator.ValidatorDefinition; + +public class FastModel implements Model { + + private final CamelContext camelContext; + + private final List<RouteDefinition> routeDefinitions = new ArrayList<>(); + private final List<RestDefinition> restDefinitions = new ArrayList<>(); + private Map<String, DataFormatDefinition> dataFormats = new HashMap<>(); + private List<TransformerDefinition> transformers = new ArrayList<>(); + private List<ValidatorDefinition> validators = new ArrayList<>(); + private Map<String, ServiceCallConfigurationDefinition> serviceCallConfigurations = new ConcurrentHashMap<>(); + private Map<String, HystrixConfigurationDefinition> hystrixConfigurations = new ConcurrentHashMap<>(); + private Map<String, Resilience4jConfigurationDefinition> resilience4jConfigurations = new ConcurrentHashMap<>(); + private Function<RouteDefinition, Boolean> routeFilter; -public class FastModel extends BaseModel { public FastModel(CamelContext camelContext) { - super(camelContext); + this.camelContext = camelContext; + } + + public CamelContext getCamelContext() { + return camelContext; } @Override - protected void start(RouteDefinition routeDefinition) throws Exception { - // indicate we are staring the route using this thread so - // we are able to query this if needed - CamelContext camelContext = getCamelContext(); - AbstractCamelContext mcc = camelContext.adapt(AbstractCamelContext.class); - mcc.setStartingRoutes(true); - try { - String id = routeDefinition.idOrCreate(camelContext.adapt(ExtendedCamelContext.class).getNodeIdFactory()); - FastRouteContext routeContext = new FastRouteContext(camelContext, routeDefinition, id); - Route route = new RouteReifier(routeContext, routeDefinition).createRoute(); - FastRouteService routeService = createRouteService(route); - mcc.startRouteService(routeService, true); - } finally { - // we are done staring routes - mcc.setStartingRoutes(false); - } - } - - private FastRouteService createRouteService(Route route) { - Integer startupOrder; - String description; - boolean autoStartup; - boolean contextScopedErrorHandler; - List<Service> routeScopedServices; - - RouteDefinition definition = (RouteDefinition) route.getRouteContext().getRoute(); - startupOrder = definition.getStartupOrder(); - description = RouteDefinitionHelper.getRouteMessage(definition.toString()); - - if (!route.getCamelContext().isAutoStartup()) { - autoStartup = false; - } else if (definition.getAutoStartup() == null) { - // should auto startup by default - autoStartup = true; - } else { - Boolean isAutoStartup = CamelContextHelper.parseBoolean(route.getCamelContext(), definition.getAutoStartup()); - autoStartup = isAutoStartup != null && isAutoStartup; - } - - if (!definition.isContextScopedErrorHandler()) { - contextScopedErrorHandler = false; - } else if (definition.getErrorHandlerRef() != null) { - // if error handler ref is configured it may refer to a context scoped, so we need to check this first - // the XML DSL will configure error handlers using refs, so we need this additional test - ErrorHandlerFactory routeScoped = route.getRouteContext().getErrorHandlerFactory(); - ErrorHandlerFactory contextScoped = route.getCamelContext().adapt(ExtendedCamelContext.class) - .getErrorHandlerFactory(); - contextScopedErrorHandler = contextScoped != null && routeScoped == contextScoped; - } else { - contextScopedErrorHandler = true; - } - - List<Service> services = new ArrayList<>(); - for (ProcessorDefinition<?> output : definition.getOutputs()) { - if (output instanceof OnExceptionDefinition) { - OnExceptionDefinition onExceptionDefinition = (OnExceptionDefinition) output; - if (onExceptionDefinition.isRouteScoped()) { - Processor errorHandler = route.getRouteContext().getOnException(onExceptionDefinition.getId()); - if (errorHandler instanceof Service) { - services.add((Service) errorHandler); - } - } - } else if (output instanceof OnCompletionDefinition) { - OnCompletionDefinition onCompletionDefinition = (OnCompletionDefinition) output; - if (onCompletionDefinition.isRouteScoped()) { - Processor onCompletionProcessor = route.getRouteContext().getOnCompletion(onCompletionDefinition.getId()); - if (onCompletionProcessor instanceof Service) { - services.add((Service) onCompletionProcessor); - } - } - } + public synchronized void addRouteDefinitions(Collection<RouteDefinition> routeDefinitions) throws Exception { + if (routeDefinitions == null || routeDefinitions.isEmpty()) { + return; } - routeScopedServices = services; + List<RouteDefinition> list = new ArrayList<>(); + routeDefinitions.forEach(r -> { + if (routeFilter == null || routeFilter.apply(r)) { + list.add(r); + } + }); - FastRouteService routeService = new FastRouteService(route); - routeService.setStartupOrder(startupOrder); - routeService.setDescription(description); - routeService.setAutoStartup(autoStartup); - routeService.setContextScopedErrorHandler(contextScopedErrorHandler); - routeService.setRouteScopedServices(routeScopedServices); - return routeService; + removeRouteDefinitions(list); + this.routeDefinitions.addAll(list); + if (shouldStartRoutes()) { + getCamelContext().adapt(ModelCamelContext.class).startRouteDefinitions(list); + } } - static class FastRouteContext extends DefaultRouteContext { - - private NamedNode route; + @Override + public void addRouteDefinition(RouteDefinition routeDefinition) throws Exception { + addRouteDefinitions(Collections.singletonList(routeDefinition)); + } - public FastRouteContext(CamelContext camelContext, NamedNode route, String routeId) { - super(camelContext, null, routeId); - this.route = route; + @Override + public synchronized void removeRouteDefinitions(Collection<RouteDefinition> routeDefinitions) throws Exception { + for (RouteDefinition routeDefinition : routeDefinitions) { + removeRouteDefinition(routeDefinition); } + } - @Override - public NamedNode getRoute() { - return route; + @Override + public synchronized void removeRouteDefinition(RouteDefinition routeDefinition) throws Exception { + RouteDefinition toBeRemoved = routeDefinition; + String id = routeDefinition.getId(); + if (id != null) { + // remove existing route + camelContext.getRouteController().stopRoute(id); + camelContext.removeRoute(id); + toBeRemoved = getRouteDefinition(id); } + this.routeDefinitions.remove(toBeRemoved); + } - public void clearModel() { - clearModel(getRuntimeRoute().getProcessor()); - route = null; - } + @Override + public synchronized List<RouteDefinition> getRouteDefinitions() { + return routeDefinitions; + } - @SuppressWarnings("unchecked") - private void clearModel(Processor nav) { - if (nav instanceof DefaultChannel) { - DefaultChannel channel = (DefaultChannel) nav; - channel.setDefinition(null); - } - if (nav instanceof Navigate) { - List<Processor> children = ((Navigate<Processor>) nav).next(); - if (children != null) { - for (Processor p : children) { - clearModel(p); - } - } + @Override + public synchronized RouteDefinition getRouteDefinition(String id) { + for (RouteDefinition route : routeDefinitions) { + if (route.idOrCreate(camelContext.adapt(ExtendedCamelContext.class).getNodeIdFactory()).equals(id)) { + return route; } } - + return null; } - static class FastRouteService extends BaseRouteService { + @Override + public synchronized List<RestDefinition> getRestDefinitions() { + return restDefinitions; + } - private Integer startupOrder; - private String description; - private boolean autoStartup; - private boolean contextScopedErrorHandler; - private List<Service> routeScopedServices; + @Override + public synchronized void addRestDefinitions(Collection<RestDefinition> restDefinitions, boolean addToRoutes) + throws Exception { + if (restDefinitions == null || restDefinitions.isEmpty()) { + return; + } - public FastRouteService(Route route) { - super(route); + this.restDefinitions.addAll(restDefinitions); + if (addToRoutes) { + // rests are also routes so need to add them there too + for (final RestDefinition restDefinition : restDefinitions) { + List<RouteDefinition> routeDefinitions = restDefinition.asRouteDefinition(camelContext); + addRouteDefinitions(routeDefinitions); + } } + } - public void setStartupOrder(Integer startupOrder) { - this.startupOrder = startupOrder; + @Override + public ServiceCallConfigurationDefinition getServiceCallConfiguration(String serviceName) { + if (serviceName == null) { + serviceName = ""; } - public void setDescription(String description) { - this.description = description; + return serviceCallConfigurations.get(serviceName); + } + + @Override + public void setServiceCallConfiguration(ServiceCallConfigurationDefinition configuration) { + serviceCallConfigurations.put("", configuration); + } + + @Override + public void setServiceCallConfigurations(List<ServiceCallConfigurationDefinition> configurations) { + if (configurations != null) { + for (ServiceCallConfigurationDefinition configuration : configurations) { + serviceCallConfigurations.put(configuration.getId(), configuration); + } } + } - public void setAutoStartup(boolean autoStartup) { - this.autoStartup = autoStartup; + @Override + public void addServiceCallConfiguration(String serviceName, ServiceCallConfigurationDefinition configuration) { + serviceCallConfigurations.put(serviceName, configuration); + } + + @Override + public HystrixConfigurationDefinition getHystrixConfiguration(String id) { + if (id == null) { + id = ""; } - public void setContextScopedErrorHandler(boolean contextScopedErrorHandler) { - this.contextScopedErrorHandler = contextScopedErrorHandler; + return hystrixConfigurations.get(id); + } + + @Override + public void setHystrixConfiguration(HystrixConfigurationDefinition configuration) { + hystrixConfigurations.put("", configuration); + } + + @Override + public void setHystrixConfigurations(List<HystrixConfigurationDefinition> configurations) { + if (configurations != null) { + for (HystrixConfigurationDefinition configuration : configurations) { + hystrixConfigurations.put(configuration.getId(), configuration); + } } + } - public void setRouteScopedServices(List<Service> routeScopedServices) { - this.routeScopedServices = routeScopedServices; + @Override + public void addHystrixConfiguration(String id, HystrixConfigurationDefinition configuration) { + hystrixConfigurations.put(id, configuration); + } + + @Override + public Resilience4jConfigurationDefinition getResilience4jConfiguration(String id) { + if (id == null) { + id = ""; } - @Override - public Integer getStartupOrder() { - return startupOrder; + return resilience4jConfigurations.get(id); + } + + @Override + public void setResilience4jConfiguration(Resilience4jConfigurationDefinition configuration) { + resilience4jConfigurations.put("", configuration); + } + + @Override + public void setResilience4jConfigurations(List<Resilience4jConfigurationDefinition> configurations) { + if (configurations != null) { + for (Resilience4jConfigurationDefinition configuration : configurations) { + resilience4jConfigurations.put(configuration.getId(), configuration); + } } + } + + @Override + public void addResilience4jConfiguration(String id, Resilience4jConfigurationDefinition configuration) { + resilience4jConfigurations.put(id, configuration); + } - @Override - protected String getRouteDescription() { - return description; + @Override + public DataFormatDefinition resolveDataFormatDefinition(String name) { + // lookup type and create the data format from it + DataFormatDefinition type = lookup(camelContext, name, DataFormatDefinition.class); + if (type == null && getDataFormats() != null) { + type = getDataFormats().get(name); } + return type; + } - @Override - public boolean isAutoStartup() { - return autoStartup; + @Override + public ProcessorDefinition<?> getProcessorDefinition(String id) { + for (RouteDefinition route : getRouteDefinitions()) { + Iterator<ProcessorDefinition> it = ProcessorDefinitionHelper.filterTypeInOutputs(route.getOutputs(), + ProcessorDefinition.class); + while (it.hasNext()) { + ProcessorDefinition<?> proc = it.next(); + if (id.equals(proc.getId())) { + return proc; + } + } } + return null; + } - @Override - public boolean isContextScopedErrorHandler() { - return contextScopedErrorHandler; + @Override + public <T extends ProcessorDefinition<T>> T getProcessorDefinition(String id, Class<T> type) { + ProcessorDefinition<?> answer = getProcessorDefinition(id); + if (answer != null) { + return type.cast(answer); } + return null; + } + + @Override + public void setDataFormats(Map<String, DataFormatDefinition> dataFormats) { + this.dataFormats = dataFormats; + } + + @Override + public Map<String, DataFormatDefinition> getDataFormats() { + return dataFormats; + } + + @Override + public void setTransformers(List<TransformerDefinition> transformers) { + this.transformers = transformers; + } + + @Override + public List<TransformerDefinition> getTransformers() { + return transformers; + } + + @Override + public void setValidators(List<ValidatorDefinition> validators) { + this.validators = validators; + } + + @Override + public List<ValidatorDefinition> getValidators() { + return validators; + } + + @Override + public void setRouteFilterPattern(String include, String exclude) { + setRouteFilter(RouteFilters.filterByPattern(include, exclude)); + } + + @Override + public Function<RouteDefinition, Boolean> getRouteFilter() { + return routeFilter; + } - @Override - protected void doGetRouteScopedServices(List<Service> services) { - services.addAll(routeScopedServices); + @Override + public void setRouteFilter(Function<RouteDefinition, Boolean> routeFilter) { + this.routeFilter = routeFilter; + } + + /** + * Should we start newly added routes? + */ + protected boolean shouldStartRoutes() { + return camelContext.isStarted() && !camelContext.isStarting(); + } + + protected static <T> T lookup(CamelContext context, String ref, Class<T> type) { + try { + return context.getRegistry().lookupByNameAndType(ref, type); + } catch (Exception e) { + // need to ignore not same type and return it as null + return null; } } diff --git a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastTypeConverter.java b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastTypeConverter.java index 178250f..641e13d 100644 --- a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastTypeConverter.java +++ b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastTypeConverter.java @@ -38,6 +38,5 @@ public class FastTypeConverter extends DefaultTypeConverter { @Override public void loadCoreAndFastTypeConverters() throws Exception { - throw new UnsupportedOperationException(); } } diff --git a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/Flags.java b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/Flags.java index a62c51d..d6c3c32 100644 --- a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/Flags.java +++ b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/Flags.java @@ -16,6 +16,7 @@ */ package org.apache.camel.quarkus.core; +import java.util.Optional; import java.util.function.BooleanSupplier; import org.eclipse.microprofile.config.ConfigProvider; @@ -25,7 +26,9 @@ public final class Flags { } private static boolean asBoolean(String key, boolean defaultValue) { - return ConfigProvider.getConfig().getOptionalValue(key, Boolean.class).orElse(defaultValue); + Optional<Boolean> b = ConfigProvider.getConfig().getOptionalValue(key, Boolean.class); + System.out.println(key + ": " + b + " (default: " + defaultValue + ")"); + return b.orElse(defaultValue); } public static final class MainEnabled implements BooleanSupplier { @@ -35,6 +38,13 @@ public final class Flags { } } + public static final class LightweightEnabled implements BooleanSupplier { + @Override + public boolean getAsBoolean() { + return asBoolean("quarkus.camel.main.lightweight", true); + } + } + public static final class RoutesDiscoveryEnabled implements BooleanSupplier { @Override public boolean getAsBoolean() { diff --git a/extensions-core/reactive-executor/deployment/src/main/java/org/apache/camel/quarkus/reactive/executor/deployment/BuildProcessor.java b/extensions-core/reactive-executor/deployment/src/main/java/org/apache/camel/quarkus/reactive/executor/deployment/BuildProcessor.java index 77020e9..8a3a949 100644 --- a/extensions-core/reactive-executor/deployment/src/main/java/org/apache/camel/quarkus/reactive/executor/deployment/BuildProcessor.java +++ b/extensions-core/reactive-executor/deployment/src/main/java/org/apache/camel/quarkus/reactive/executor/deployment/BuildProcessor.java @@ -25,7 +25,7 @@ import org.apache.camel.quarkus.core.deployment.CamelReactiveExecutorBuildItem; import org.apache.camel.quarkus.reactive.executor.ReactiveExecutorRecorder; public class BuildProcessor { - @Record(value = ExecutionTime.RUNTIME_INIT, optional = true) + @Record(value = ExecutionTime.STATIC_INIT, optional = true) @BuildStep(onlyIf = Flags.MainEnabled.class) CamelReactiveExecutorBuildItem reactiveExecutor(ReactiveExecutorRecorder recorder, VertxBuildItem vertx) { return new CamelReactiveExecutorBuildItem(recorder.createReactiveExecutor(vertx.getVertx())); diff --git a/extensions-core/xml-jaxb/runtime/src/main/java/org/apache/camel/quarkus/component/xml/jaxb/XmlJaxbRecorder.java b/extensions-core/xml-jaxb/runtime/src/main/java/org/apache/camel/quarkus/component/xml/jaxb/XmlJaxbRecorder.java index 3cb9e69..260da00 100644 --- a/extensions-core/xml-jaxb/runtime/src/main/java/org/apache/camel/quarkus/component/xml/jaxb/XmlJaxbRecorder.java +++ b/extensions-core/xml-jaxb/runtime/src/main/java/org/apache/camel/quarkus/component/xml/jaxb/XmlJaxbRecorder.java @@ -21,10 +21,10 @@ import javax.xml.bind.JAXBException; import io.quarkus.runtime.RuntimeValue; import io.quarkus.runtime.annotations.Recorder; import org.apache.camel.RuntimeCamelException; -import org.apache.camel.impl.DefaultModelJAXBContextFactory; import org.apache.camel.spi.ModelJAXBContextFactory; import org.apache.camel.spi.ModelToXMLDumper; import org.apache.camel.spi.XMLRoutesDefinitionLoader; +import org.apache.camel.xml.jaxb.DefaultModelJAXBContextFactory; import org.apache.camel.xml.jaxb.JaxbModelToXMLDumper; import org.apache.camel.xml.jaxb.JaxbXMLRoutesDefinitionLoader; import org.graalvm.nativeimage.ImageInfo; diff --git a/extensions/kotlin/runtime/src/main/kotlin/org/apache/camel/quarkus/kotlin/RoutesDSL.kt b/extensions/kotlin/runtime/src/main/kotlin/org/apache/camel/quarkus/kotlin/RoutesDSL.kt index 1412771..a4bae25 100644 --- a/extensions/kotlin/runtime/src/main/kotlin/org/apache/camel/quarkus/kotlin/RoutesDSL.kt +++ b/extensions/kotlin/runtime/src/main/kotlin/org/apache/camel/quarkus/kotlin/RoutesDSL.kt @@ -26,7 +26,7 @@ import org.apache.camel.builder.RouteBuilder * * ``` * fun myRoutes() = routes { - * from("timer:foo?period=1s") + * from("timer:foo?period=1000") * .log("\${body}") * } * ``` diff --git a/extensions/microprofile-health/deployment/src/main/java/org/apache/camel/quarkus/component/microprofile/health/deployment/MicroProfileHealthProcessor.java b/extensions/microprofile-health/deployment/src/main/java/org/apache/camel/quarkus/component/microprofile/health/deployment/MicroProfileHealthProcessor.java index 8b04405..c7f7d84 100644 --- a/extensions/microprofile-health/deployment/src/main/java/org/apache/camel/quarkus/component/microprofile/health/deployment/MicroProfileHealthProcessor.java +++ b/extensions/microprofile-health/deployment/src/main/java/org/apache/camel/quarkus/component/microprofile/health/deployment/MicroProfileHealthProcessor.java @@ -25,6 +25,8 @@ import javax.enterprise.inject.Vetoed; import io.quarkus.arc.deployment.AnnotationsTransformerBuildItem; import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.annotations.ExecutionTime; +import io.quarkus.deployment.annotations.Record; import io.quarkus.deployment.builditem.CombinedIndexBuildItem; import io.quarkus.deployment.builditem.FeatureBuildItem; import org.apache.camel.health.HealthCheck; @@ -58,6 +60,7 @@ class MicroProfileHealthProcessor { return new FeatureBuildItem(FEATURE); } + @Record(ExecutionTime.STATIC_INIT) @BuildStep List<CamelBeanBuildItem> camelHealthDiscovery( CombinedIndexBuildItem combinedIndex, diff --git a/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteComponentConfigurer.java b/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteComponentConfigurer.java index 37d5e07..0e903b1 100644 --- a/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteComponentConfigurer.java +++ b/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteComponentConfigurer.java @@ -1,29 +1,55 @@ /* Generated by camel build tools - do NOT edit this file! */ package org.apache.camel.component.qute; +import java.util.Map; + import org.apache.camel.CamelContext; import org.apache.camel.spi.GeneratedPropertyConfigurer; +import org.apache.camel.spi.PropertyConfigurerGetter; +import org.apache.camel.util.CaseInsensitiveMap; import org.apache.camel.support.component.PropertyConfigurerSupport; /** * Generated by camel build tools - do NOT edit this file! */ @SuppressWarnings("unchecked") -public class QuteComponentConfigurer extends PropertyConfigurerSupport implements GeneratedPropertyConfigurer { +public class QuteComponentConfigurer extends PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter { @Override public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) { QuteComponent target = (QuteComponent) obj; switch (ignoreCase ? name.toLowerCase() : name) { - case "lazystartproducer": - case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true; case "basicpropertybinding": case "basicPropertyBinding": target.setBasicPropertyBinding(property(camelContext, boolean.class, value)); return true; + case "lazystartproducer": + case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true; case "quteengine": case "quteEngine": target.setQuteEngine(property(camelContext, io.quarkus.qute.Engine.class, value)); return true; default: return false; } } + @Override + public Map<String, Object> getAllOptions(Object target) { + Map<String, Object> answer = new CaseInsensitiveMap(); + answer.put("basicPropertyBinding", boolean.class); + answer.put("lazyStartProducer", boolean.class); + answer.put("quteEngine", io.quarkus.qute.Engine.class); + return answer; + } + + @Override + public Object getOptionValue(Object obj, String name, boolean ignoreCase) { + QuteComponent target = (QuteComponent) obj; + switch (ignoreCase ? name.toLowerCase() : name) { + case "basicpropertybinding": + case "basicPropertyBinding": return target.isBasicPropertyBinding(); + case "lazystartproducer": + case "lazyStartProducer": return target.isLazyStartProducer(); + case "quteengine": + case "quteEngine": return target.getQuteEngine(); + default: return null; + } + } } diff --git a/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteEndpointConfigurer.java b/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteEndpointConfigurer.java index 86093a9..059e63e 100644 --- a/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteEndpointConfigurer.java +++ b/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteEndpointConfigurer.java @@ -1,31 +1,61 @@ /* Generated by camel build tools - do NOT edit this file! */ package org.apache.camel.component.qute; +import java.util.Map; + import org.apache.camel.CamelContext; import org.apache.camel.spi.GeneratedPropertyConfigurer; +import org.apache.camel.spi.PropertyConfigurerGetter; +import org.apache.camel.util.CaseInsensitiveMap; import org.apache.camel.support.component.PropertyConfigurerSupport; /** * Generated by camel build tools - do NOT edit this file! */ @SuppressWarnings("unchecked") -public class QuteEndpointConfigurer extends PropertyConfigurerSupport implements GeneratedPropertyConfigurer { +public class QuteEndpointConfigurer extends PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter { @Override public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) { QuteEndpoint target = (QuteEndpoint) obj; switch (ignoreCase ? name.toLowerCase() : name) { + case "basicpropertybinding": + case "basicPropertyBinding": target.setBasicPropertyBinding(property(camelContext, boolean.class, value)); return true; case "contentcache": case "contentCache": target.setContentCache(property(camelContext, boolean.class, value)); return true; case "encoding": target.setEncoding(property(camelContext, java.lang.String.class, value)); return true; case "lazystartproducer": case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true; - case "basicpropertybinding": - case "basicPropertyBinding": target.setBasicPropertyBinding(property(camelContext, boolean.class, value)); return true; case "synchronous": target.setSynchronous(property(camelContext, boolean.class, value)); return true; default: return false; } } + @Override + public Map<String, Object> getAllOptions(Object target) { + Map<String, Object> answer = new CaseInsensitiveMap(); + answer.put("basicPropertyBinding", boolean.class); + answer.put("contentCache", boolean.class); + answer.put("encoding", java.lang.String.class); + answer.put("lazyStartProducer", boolean.class); + answer.put("synchronous", boolean.class); + return answer; + } + + @Override + public Object getOptionValue(Object obj, String name, boolean ignoreCase) { + QuteEndpoint target = (QuteEndpoint) obj; + switch (ignoreCase ? name.toLowerCase() : name) { + case "basicpropertybinding": + case "basicPropertyBinding": return target.isBasicPropertyBinding(); + case "contentcache": + case "contentCache": return target.isContentCache(); + case "encoding": return target.getEncoding(); + case "lazystartproducer": + case "lazyStartProducer": return target.isLazyStartProducer(); + case "synchronous": return target.isSynchronous(); + default: return null; + } + } } diff --git a/pom.xml b/pom.xml index a03c24f..21cb303 100644 --- a/pom.xml +++ b/pom.xml @@ -44,7 +44,7 @@ <ahc.version>2.10.4</ahc.version> <awssdk1.version>1.11.714</awssdk1.version> <awssdk1-swf-libs.version>1.11.22</awssdk1-swf-libs.version> - <awssdk2.version>2.10.67</awssdk2.version> + <awssdk2.version>2.11.4</awssdk2.version> <camel.version>3.2.0-SNAPSHOT</camel.version> <freemarker.version>2.3.30</freemarker.version> <google-http-client.version>1.22.0</google-http-client.version> diff --git a/poms/bom/pom.xml b/poms/bom/pom.xml index 91a64b7..10436ab 100644 --- a/poms/bom/pom.xml +++ b/poms/bom/pom.xml @@ -1886,6 +1886,21 @@ <version>${jackson.version}</version> </dependency> <dependency> + <groupId>com.google.api.grpc</groupId> + <artifactId>proto-google-common-protos</artifactId> + <version>1.17.0</version> + </dependency> + <dependency> + <groupId>com.google.auth</groupId> + <artifactId>google-auth-library-credentials</artifactId> + <version>0.19.0</version> + </dependency> + <dependency> + <groupId>com.google.auth</groupId> + <artifactId>google-auth-library-oauth2-http</artifactId> + <version>0.19.0</version> + </dependency> + <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>${gson.version}</version> @@ -1907,6 +1922,11 @@ </exclusions> </dependency> <dependency> + <groupId>com.google.protobuf</groupId> + <artifactId>protobuf-java</artifactId> + <version>3.11.0</version> + </dependency> + <dependency> <groupId>com.orbitz.consul</groupId> <artifactId>consul-client</artifactId> <version>${consul-client.version}</version> @@ -1959,6 +1979,11 @@ <version>${ahc.version}</version> </dependency> <dependency> + <groupId>org.codehaus.mojo</groupId> + <artifactId>animal-sniffer-annotations</artifactId> + <version>1.18</version> + </dependency> + <dependency> <groupId>org.codehaus.woodstox</groupId> <artifactId>stax2-api</artifactId> <version>${stax2.version}</version> @@ -2015,6 +2040,16 @@ <version>${snakeyaml.version}</version> </dependency> <dependency> + <groupId>org.threeten</groupId> + <artifactId>threetenbp</artifactId> + <version>1.4.0</version> + </dependency> + <dependency> + <groupId>software.amazon.awssdk</groupId> + <artifactId>annotations</artifactId> + <version>${awssdk2.version}</version><!-- override the version set in the quarkus BOM --> + </dependency> + <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>apache-client</artifactId> <version>${awssdk2.version}</version><!-- override the version set in the quarkus BOM --> @@ -2026,6 +2061,11 @@ </dependency> <dependency> <groupId>software.amazon.awssdk</groupId> + <artifactId>http-client-spi</artifactId> + <version>${awssdk2.version}</version><!-- override the version set in the quarkus BOM --> + </dependency> + <dependency> + <groupId>software.amazon.awssdk</groupId> <artifactId>netty-nio-client</artifactId> <version>${awssdk2.version}</version><!-- override the version set in the quarkus BOM --> </dependency> @@ -2035,6 +2075,11 @@ <version>${awssdk2.version}</version><!-- override the version set in the quarkus BOM --> </dependency> <dependency> + <groupId>software.amazon.awssdk</groupId> + <artifactId>utils</artifactId> + <version>${awssdk2.version}</version><!-- override the version set in the quarkus BOM --> + </dependency> + <dependency> <groupId>xalan</groupId> <artifactId>xalan</artifactId> <version>${xalan.version}</version>
