This is an automated email from the ASF dual-hosted git repository.

ppalaga pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git


The following commit(s) were added to refs/heads/main by this push:
     new 89342a6  Support @EndpointInject and @Produce #2539
89342a6 is described below

commit 89342a6aa0ad67128a16be9f512c19c24342a351
Author: Peter Palaga <ppal...@redhat.com>
AuthorDate: Fri Apr 30 16:06:46 2021 +0200

    Support @EndpointInject and @Produce #2539
---
 docs/modules/ROOT/pages/user-guide/cdi.adoc        |  70 ++++++
 .../core/deployment/InjectionPointsProcessor.java  | 246 +++++++++++++++++++++
 .../apache/camel/quarkus/core/CamelProducers.java  |  28 +--
 .../apache/camel/quarkus/core/CamelRecorder.java   |  52 +++++
 .../quarkus/support/common/CamelCapabilities.java  |   1 +
 .../component/bean/deployment/BeanProcessor.java   |   7 +
 .../camel/quarkus/component/bean/BeanResource.java |  49 ++--
 .../camel/quarkus/component/bean/BeanRoutes.java   |  12 +
 .../quarkus/component/bean/method/Producers.java   |   1 +
 .../camel/quarkus/component/bean/BeanTest.java     |  23 +-
 .../apache/camel/quarkus/core/CoreResource.java    |   7 +-
 .../core/annotations/CoreAnnotationsResource.java  | 123 +++++++++++
 .../core/annotations/CoreAnnotationsRoutes.java    |  86 +++++++
 .../camel/quarkus/core/CoreAnnotationsIT.java}     |  20 +-
 .../camel/quarkus/core/CoreAnnotationsTest.java    |  88 ++++++++
 .../java/org/apache/camel/quarkus/core/CoreIT.java |  14 +-
 .../org/apache/camel/quarkus/core/CoreTest.java    |  40 ++--
 17 files changed, 776 insertions(+), 91 deletions(-)

diff --git a/docs/modules/ROOT/pages/user-guide/cdi.adoc 
b/docs/modules/ROOT/pages/user-guide/cdi.adoc
index 7f43555..8d05098 100644
--- a/docs/modules/ROOT/pages/user-guide/cdi.adoc
+++ b/docs/modules/ROOT/pages/user-guide/cdi.adoc
@@ -65,8 +65,78 @@ public static class MyBean {
 }
 ----
 
+== `@EndpoinInject` and `@Produce`
+
+If you are used to `@org.apache.camel.EndpointInject` and 
`@org.apache.camel.Produce` from
+xref:latest@manual::pojo-producing.adoc[plain Camel] or from Camel on 
SpringBoot, you can continue using them on Quarkus too.
+
+The following use cases are supported by 
`org.apache.camel.quarkus:camel-quarkus-core`:
+
+[source,java]
+----
+import javax.enterprise.context.ApplicationScoped;
+import org.apache.camel.EndpointInject;
+import org.apache.camel.FluentProducerTemplate;
+import org.apache.camel.Produce;
+import org.apache.camel.ProducerTemplate;
+
+@ApplicationScoped
+class MyBean {
+
+    @EndpointInject("direct:myDirect1")
+    ProducerTemplate producerTemplate;
+
+    @EndpointInject("direct:myDirect2")
+    FluentProducerTemplate fluentProducerTemplate;
+
+    @EndpointInject("direct:myDirect3")
+    DirectEndpoint directEndpoint;
+
+    @Produce("direct:myDirect4")
+    ProducerTemplate produceProducer;
+
+    @Produce("direct:myDirect5")
+    FluentProducerTemplate produceProducerFluent;
+
+}
+----
+
+You can use any other Camel producer endpoint URI instead of 
`direct:myDirect*`.
+
+[WARNING]
+====
+`@EndpoinInject` and `@Produce` are not supported on setter methods
+- see https://github.com/apache/camel-quarkus/issues/2579[#2579]
+====
+
+The following use case is supported by 
`org.apache.camel.quarkus:camel-quarkus-bean`:
+
+[source,java]
+----
+import javax.enterprise.context.ApplicationScoped;
+import org.apache.camel.Produce;
+
+@ApplicationScoped
+class MyProduceBean {
+
+    public interface ProduceInterface {
+        String sayHello(String name);
+    }
+
+    @Produce("direct:myDirect6")
+    ProduceInterface produceInterface;
+
+    void doSomething() {
+        produceInterface.sayHello("Kermit")
+    }
+
+}
+----
+
 == CDI and the Camel Bean component
 
+`org.apache.camel.quarkus:camel-quarkus-bean` artifact brings support for the 
following features:
+
 === Refer to a bean by name
 
 To refer to a bean in a route definition by name, just annotate the bean with 
`@Named("myNamedBean")` and
diff --git 
a/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/InjectionPointsProcessor.java
 
b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/InjectionPointsProcessor.java
index fded90c..6dfbb19 100644
--- 
a/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/InjectionPointsProcessor.java
+++ 
b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/InjectionPointsProcessor.java
@@ -17,29 +17,48 @@
 package org.apache.camel.quarkus.core.deployment;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Supplier;
 
+import javax.inject.Inject;
 import javax.inject.Named;
 import javax.inject.Singleton;
 
+import io.quarkus.arc.deployment.AnnotationsTransformerBuildItem;
 import io.quarkus.arc.deployment.BeanRegistrationPhaseBuildItem;
+import io.quarkus.arc.deployment.QualifierRegistrarBuildItem;
 import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
+import io.quarkus.arc.processor.AnnotationsTransformer;
 import io.quarkus.arc.processor.BuildExtension;
 import io.quarkus.arc.processor.InjectionPointInfo;
+import io.quarkus.arc.processor.QualifierRegistrar;
 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.CapabilityBuildItem;
 import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
+import 
io.quarkus.deployment.builditem.nativeimage.NativeImageProxyDefinitionBuildItem;
 import org.apache.camel.Component;
+import org.apache.camel.Endpoint;
+import org.apache.camel.EndpointInject;
+import org.apache.camel.FluentProducerTemplate;
+import org.apache.camel.Produce;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.quarkus.core.CamelRecorder;
 import org.apache.camel.quarkus.core.InjectionPointsRecorder;
 import org.apache.camel.quarkus.core.deployment.spi.CamelRuntimeTaskBuildItem;
+import org.apache.camel.quarkus.support.common.CamelCapabilities;
 import org.jboss.jandex.AnnotationInstance;
 import org.jboss.jandex.AnnotationTarget;
+import org.jboss.jandex.AnnotationTarget.Kind;
 import org.jboss.jandex.ClassInfo;
 import org.jboss.jandex.DotName;
 import org.jboss.jandex.FieldInfo;
@@ -54,6 +73,10 @@ public class InjectionPointsProcessor {
             Named.class.getName());
     private static final DotName INTERFACE_NAME_COMPONENT = 
DotName.createSimple(
             Component.class.getName());
+    private static final DotName ENDPOINT_INJECT_ANNOTATION = DotName
+            .createSimple(EndpointInject.class.getName());
+    private static final DotName PRODUCE_ANNOTATION = DotName
+            .createSimple(Produce.class.getName());
 
     private static SyntheticBeanBuildItem syntheticBean(DotName name, 
Supplier<?> creator) {
         return SyntheticBeanBuildItem.configure(name)
@@ -129,4 +152,227 @@ public class InjectionPointsProcessor {
         // See BeanRegistrationPhaseBuildItem javadoc
         beanConfigurator.produce(new 
BeanRegistrationPhaseBuildItem.BeanConfiguratorBuildItem());
     }
+
+    @BuildStep
+    void annotationsTransformers(
+            BuildProducer<AnnotationsTransformerBuildItem> 
annotationsTransformers) {
+
+        annotationsTransformers.produce(new 
AnnotationsTransformerBuildItem(new AnnotationsTransformer() {
+
+            public boolean appliesTo(org.jboss.jandex.AnnotationTarget.Kind 
kind) {
+                return kind == Kind.FIELD || kind == Kind.METHOD;
+            }
+
+            @Override
+            public void transform(TransformationContext ctx) {
+
+                final AnnotationTarget target = ctx.getTarget();
+                switch (target.kind()) {
+                case FIELD: {
+                    final FieldInfo fieldInfo = target.asField();
+                    if (fieldInfo.annotation(ENDPOINT_INJECT_ANNOTATION) != 
null
+                            || fieldInfo.annotation(PRODUCE_ANNOTATION) != 
null) {
+                        ctx.transform().add(Inject.class).done();
+                    }
+                    break;
+                }
+                case METHOD: {
+                    final MethodInfo methodInfo = target.asMethod();
+                    fail(methodInfo, ENDPOINT_INJECT_ANNOTATION);
+                    fail(methodInfo, PRODUCE_ANNOTATION);
+                    break;
+                }
+                default:
+                    throw new IllegalStateException("Expected only field or 
method, got " + target.kind());
+                }
+
+            }
+
+        }));
+
+    }
+
+    static void fail(final MethodInfo methodInfo, DotName annotType) {
+        if (methodInfo.annotation(annotType) != null) {
+            // See https://github.com/apache/camel-quarkus/issues/2579
+            throw new IllegalStateException(
+                    "@" + annotType + " is only supported on fields. Remove it 
from "
+                            + methodInfo + " in " + 
methodInfo.declaringClass().name());
+        }
+    }
+
+    @BuildStep
+    void qualifierRegistrars(
+            BuildProducer<QualifierRegistrarBuildItem> qualifierRegistrars) {
+        qualifierRegistrars.produce(new QualifierRegistrarBuildItem(new 
QualifierRegistrar() {
+
+            @Override
+            public Map<DotName, Set<String>> getAdditionalQualifiers() {
+                Map<DotName, Set<String>> result = new LinkedHashMap<DotName, 
Set<String>>();
+                result.put(ENDPOINT_INJECT_ANNOTATION, Collections.emptySet());
+                result.put(PRODUCE_ANNOTATION, Collections.emptySet());
+                return Collections.unmodifiableMap(result);
+            }
+        }));
+    }
+
+    @Record(value = ExecutionTime.RUNTIME_INIT, optional = true)
+    @BuildStep
+    void syntheticBeans(
+            CamelRecorder recorder,
+            CombinedIndexBuildItem index,
+            List<CapabilityBuildItem> capabilities,
+            BuildProducer<SyntheticBeanBuildItem> syntheticBeans,
+            BuildProducer<NativeImageProxyDefinitionBuildItem> 
proxyDefinitions) {
+
+        for (AnnotationInstance annot : 
index.getIndex().getAnnotations(ENDPOINT_INJECT_ANNOTATION)) {
+            final AnnotationTarget target = annot.target();
+            switch (target.kind()) {
+            case FIELD: {
+                final FieldInfo field = target.asField();
+                endpointInjectBeans(recorder, syntheticBeans, annot, 
field.type().name());
+                break;
+            }
+            case METHOD: {
+                final MethodInfo methodInfo = target.asMethod();
+                fail(methodInfo, ENDPOINT_INJECT_ANNOTATION);
+                break;
+            }
+            default:
+                throw new IllegalStateException("Expected field, got " + 
target.kind());
+            }
+        }
+
+        AtomicReference<Boolean> beanCapabilityAvailable = new 
AtomicReference<>();
+
+        for (AnnotationInstance annot : 
index.getIndex().getAnnotations(PRODUCE_ANNOTATION)) {
+            final AnnotationTarget target = annot.target();
+            switch (target.kind()) {
+            case FIELD: {
+                final FieldInfo field = target.asField();
+                produceBeans(recorder, capabilities, syntheticBeans, 
proxyDefinitions, beanCapabilityAvailable, annot,
+                        field.type().name(), field.name(), 
field.declaringClass().name());
+                break;
+            }
+            case METHOD: {
+                final MethodInfo methodInfo = target.asMethod();
+                fail(methodInfo, PRODUCE_ANNOTATION);
+                break;
+            }
+            default:
+                throw new IllegalStateException("Expected field, got " + 
target.kind());
+            }
+        }
+    }
+
+    void produceBeans(CamelRecorder recorder, List<CapabilityBuildItem> 
capabilities,
+            BuildProducer<SyntheticBeanBuildItem> syntheticBeans,
+            BuildProducer<NativeImageProxyDefinitionBuildItem> 
proxyDefinitions,
+            AtomicReference<Boolean> beanCapabilityAvailable,
+            AnnotationInstance annot, final DotName fieldType, String 
annotationTarget, DotName declaringClass) {
+        try {
+            Class<?> clazz = Class.forName(fieldType.toString(), false,
+                    Thread.currentThread().getContextClassLoader());
+            if (ProducerTemplate.class.isAssignableFrom(clazz)) {
+                syntheticBeans.produce(
+                        SyntheticBeanBuildItem
+                                .configure(fieldType)
+                                .setRuntimeInit().scope(Singleton.class)
+                                .supplier(
+                                        
recorder.createProducerTemplate(annot.value().asString()))
+                                .addQualifier(annot)
+                                .done());
+                /*
+                 * Note that ProducerTemplate injection points not having 
@EndpointInject are produced via
+                 * CamelProducers.camelProducerTemplate()
+                 */
+            } else if (FluentProducerTemplate.class.isAssignableFrom(clazz)) {
+                syntheticBeans.produce(
+                        SyntheticBeanBuildItem
+                                .configure(fieldType)
+                                .setRuntimeInit().scope(Singleton.class)
+                                .supplier(
+                                        
recorder.createFluentProducerTemplate(annot.value().asString()))
+                                .addQualifier(annot)
+                                .done());
+                /*
+                 * Note that FluentProducerTemplate injection points not 
having @EndpointInject are produced via
+                 * CamelProducers.camelFluentProducerTemplate()
+                 */
+            } else if (clazz.isInterface()) {
+                /* Requires camel-quarkus-bean */
+
+                if (beanCapabilityAvailable.get() == null) {
+                    
beanCapabilityAvailable.set(capabilities.stream().map(CapabilityBuildItem::getName)
+                            .anyMatch(feature -> 
CamelCapabilities.BEAN.equals(feature)));
+                }
+                if (!beanCapabilityAvailable.get()) {
+                    throw new IllegalStateException(
+                            "Add camel-quarkus-bean dependency to be able to 
use @org.apache.camel.Produce on fields with interface type: "
+                                    + fieldType.toString()
+                                    + " " + annotationTarget + " in "
+                                    + declaringClass.toString());
+                }
+
+                proxyDefinitions.produce(new 
NativeImageProxyDefinitionBuildItem(fieldType.toString()));
+                syntheticBeans.produce(
+                        SyntheticBeanBuildItem
+                                .configure(fieldType)
+                                .setRuntimeInit().scope(Singleton.class)
+                                .supplier(
+                                        recorder.produceProxy(clazz, 
annot.value().asString()))
+                                .addQualifier(annot)
+                                .done());
+            }
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private void endpointInjectBeans(CamelRecorder recorder, 
BuildProducer<SyntheticBeanBuildItem> syntheticBeans,
+            AnnotationInstance annot, final DotName fieldType) {
+        try {
+            Class<?> clazz = Class.forName(fieldType.toString());
+            if (Endpoint.class.isAssignableFrom(clazz)) {
+                syntheticBeans.produce(
+                        SyntheticBeanBuildItem
+                                .configure(fieldType)
+                                .setRuntimeInit().scope(Singleton.class)
+                                .supplier(
+                                        
recorder.createEndpoint(annot.value().asString(),
+                                                (Class<? extends Endpoint>) 
clazz))
+                                .addQualifier(annot)
+                                .done());
+            } else if (ProducerTemplate.class.isAssignableFrom(clazz)) {
+                syntheticBeans.produce(
+                        SyntheticBeanBuildItem
+                                .configure(fieldType)
+                                .setRuntimeInit().scope(Singleton.class)
+                                .supplier(
+                                        
recorder.createProducerTemplate(annot.value().asString()))
+                                .addQualifier(annot)
+                                .done());
+                /*
+                 * Note that ProducerTemplate injection points not having 
@EndpointInject are produced via
+                 * CamelProducers.camelProducerTemplate()
+                 */
+            } else if (FluentProducerTemplate.class.isAssignableFrom(clazz)) {
+                syntheticBeans.produce(
+                        SyntheticBeanBuildItem
+                                .configure(fieldType)
+                                .setRuntimeInit().scope(Singleton.class)
+                                .supplier(
+                                        
recorder.createFluentProducerTemplate(annot.value().asString()))
+                                .addQualifier(annot)
+                                .done());
+                /*
+                 * Note that FluentProducerTemplate injection points not 
having @EndpointInject are produced via
+                 * CamelProducers.camelFluentProducerTemplate()
+                 */
+            }
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
 }
diff --git 
a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelProducers.java
 
b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelProducers.java
index 89dd4b7..3a4e4ac 100644
--- 
a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelProducers.java
+++ 
b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelProducers.java
@@ -23,10 +23,8 @@ import javax.inject.Singleton;
 import org.apache.camel.CamelContext;
 import org.apache.camel.ConsumerTemplate;
 import org.apache.camel.FluentProducerTemplate;
-import org.apache.camel.Produce;
 import org.apache.camel.ProducerTemplate;
 import org.apache.camel.spi.Registry;
-import org.apache.camel.util.ObjectHelper;
 
 /**
  * Producers of beans that are injectable via CDI.
@@ -64,26 +62,20 @@ public class CamelProducers {
 
     @Produces
     ProducerTemplate camelProducerTemplate(InjectionPoint injectionPoint) {
-        final ProducerTemplate template = 
this.context.createProducerTemplate();
-        final Produce produce = 
injectionPoint.getAnnotated().getAnnotation(Produce.class);
-
-        if (ObjectHelper.isNotEmpty(produce) && 
ObjectHelper.isNotEmpty(produce.value())) {
-            template.setDefaultEndpointUri(produce.value());
-        }
-
-        return template;
+        /*
+         * Note that ProducerTemplate injection points qualified with 
@EndpointInject and @Produce are handled in
+         * InjectionPointsProcessor.syntheticBeans()
+         */
+        return this.context.createProducerTemplate();
     }
 
     @Produces
     FluentProducerTemplate camelFluentProducerTemplate(InjectionPoint 
injectionPoint) {
-        final FluentProducerTemplate template = 
this.context.createFluentProducerTemplate();
-        final Produce produce = 
injectionPoint.getAnnotated().getAnnotation(Produce.class);
-
-        if (ObjectHelper.isNotEmpty(produce) && 
ObjectHelper.isNotEmpty(produce.value())) {
-            template.setDefaultEndpointUri(produce.value());
-        }
-
-        return template;
+        /*
+         * Note that FluentProducerTemplate injection points qualified with 
@EndpointInject and @Produce are handled in
+         * InjectionPointsProcessor.syntheticBeans()
+         */
+        return this.context.createFluentProducerTemplate();
     }
 
     @Produces
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 50c6b03..289e108 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
@@ -17,15 +17,23 @@
 package org.apache.camel.quarkus.core;
 
 import java.util.Set;
+import java.util.function.Supplier;
 
+import io.quarkus.arc.Arc;
 import io.quarkus.runtime.RuntimeValue;
 import io.quarkus.runtime.annotations.Recorder;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.FluentProducerTemplate;
+import org.apache.camel.ProducerTemplate;
 import org.apache.camel.impl.engine.DefaultReactiveExecutor;
 import org.apache.camel.model.ValidateDefinition;
 import org.apache.camel.model.validator.PredicateValidatorDefinition;
 import org.apache.camel.quarkus.core.FastFactoryFinderResolver.Builder;
 import org.apache.camel.reifier.ProcessorReifier;
 import org.apache.camel.reifier.validator.ValidatorReifier;
+import org.apache.camel.spi.BeanProxyFactory;
 import org.apache.camel.spi.FactoryFinderResolver;
 import org.apache.camel.spi.ModelJAXBContextFactory;
 import org.apache.camel.spi.ModelToXMLDumper;
@@ -133,4 +141,48 @@ public class CamelRecorder {
     public RuntimeValue<StartupStepRecorder> newDefaultStartupStepRecorder() {
         return new RuntimeValue<>(new DefaultStartupStepRecorder());
     }
+
+    public Supplier<Endpoint> createEndpoint(String uri, Class<? extends 
Endpoint> endpointClass) {
+        return () -> {
+            final CamelContext camelContext = 
Arc.container().instance(CamelContext.class).get();
+            return camelContext.getEndpoint(uri, endpointClass);
+        };
+    }
+
+    public Supplier<ProducerTemplate> createProducerTemplate(String uri) {
+        return () -> {
+            final CamelContext camelContext = 
Arc.container().instance(CamelContext.class).get();
+            final ProducerTemplate result = 
camelContext.createProducerTemplate();
+            if (uri != null) {
+                result.setDefaultEndpointUri(uri);
+            }
+            return result;
+        };
+    }
+
+    public Supplier<FluentProducerTemplate> 
createFluentProducerTemplate(String uri) {
+        return () -> {
+            final CamelContext camelContext = 
Arc.container().instance(CamelContext.class).get();
+            final FluentProducerTemplate result = 
camelContext.createFluentProducerTemplate();
+            if (uri != null) {
+                result.setDefaultEndpointUri(uri);
+            }
+            return result;
+        };
+    }
+
+    public Supplier<?> produceProxy(Class<?> clazz, String uri) {
+        return () -> {
+            final CamelContext camelContext = 
Arc.container().instance(CamelContext.class).get();
+            final BeanProxyFactory factory = 
camelContext.adapt(ExtendedCamelContext.class).getBeanProxyFactory();
+            final Endpoint endpoint = camelContext.getEndpoint(uri);
+            try {
+                return factory.createProxy(endpoint, true, clazz);
+            } catch (Exception e) {
+                throw new RuntimeException(
+                        "Could not instantiate proxy of type " + 
clazz.getName() + " on endpoint " + endpoint, e);
+            }
+        };
+    }
+
 }
diff --git 
a/extensions-support/common/runtime/src/main/java/org/apache/camel/quarkus/support/common/CamelCapabilities.java
 
b/extensions-support/common/runtime/src/main/java/org/apache/camel/quarkus/support/common/CamelCapabilities.java
index 33add79..31a042f 100644
--- 
a/extensions-support/common/runtime/src/main/java/org/apache/camel/quarkus/support/common/CamelCapabilities.java
+++ 
b/extensions-support/common/runtime/src/main/java/org/apache/camel/quarkus/support/common/CamelCapabilities.java
@@ -17,6 +17,7 @@
 package org.apache.camel.quarkus.support.common;
 
 public final class CamelCapabilities {
+    public static final String BEAN = "org.apache.camel.bean";
     public static final String CORE = "org.apache.camel";
     public static final String MAIN = "org.apache.camel.main";
     public static final String XML = "org.apache.camel.xml";
diff --git 
a/extensions/bean/deployment/src/main/java/org/apache/camel/quarkus/component/bean/deployment/BeanProcessor.java
 
b/extensions/bean/deployment/src/main/java/org/apache/camel/quarkus/component/bean/deployment/BeanProcessor.java
index 1ae9848..a3aeb78 100644
--- 
a/extensions/bean/deployment/src/main/java/org/apache/camel/quarkus/component/bean/deployment/BeanProcessor.java
+++ 
b/extensions/bean/deployment/src/main/java/org/apache/camel/quarkus/component/bean/deployment/BeanProcessor.java
@@ -18,9 +18,11 @@ package org.apache.camel.quarkus.component.bean.deployment;
 
 import io.quarkus.deployment.annotations.BuildProducer;
 import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.builditem.CapabilityBuildItem;
 import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
 import io.quarkus.deployment.builditem.FeatureBuildItem;
 import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
+import org.apache.camel.quarkus.support.common.CamelCapabilities;
 import org.apache.camel.support.language.DefaultAnnotationExpressionFactory;
 import org.apache.camel.support.language.LanguageAnnotation;
 import org.jboss.jandex.AnnotationInstance;
@@ -43,6 +45,11 @@ class BeanProcessor {
     }
 
     @BuildStep
+    CapabilityBuildItem capability() {
+        return new CapabilityBuildItem(CamelCapabilities.BEAN);
+    }
+
+    @BuildStep
     void registerReflectiveClasses(CombinedIndexBuildItem index, 
BuildProducer<ReflectiveClassBuildItem> producer) {
         IndexView view = index.getIndex();
         for (AnnotationInstance languageAnnotationInstance : 
view.getAnnotations(LANGUAGE_ANNOTATION)) {
diff --git 
a/integration-tests/bean/src/main/java/org/apache/camel/quarkus/component/bean/BeanResource.java
 
b/integration-tests/bean/src/main/java/org/apache/camel/quarkus/component/bean/BeanResource.java
index ce095bc..7df140c 100644
--- 
a/integration-tests/bean/src/main/java/org/apache/camel/quarkus/component/bean/BeanResource.java
+++ 
b/integration-tests/bean/src/main/java/org/apache/camel/quarkus/component/bean/BeanResource.java
@@ -16,8 +16,12 @@
  */
 package org.apache.camel.quarkus.component.bean;
 
+import java.util.List;
+import java.util.Map;
+
 import javax.enterprise.context.ApplicationScoped;
 import javax.inject.Inject;
+import javax.inject.Named;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
@@ -26,8 +30,8 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
 
-import org.apache.camel.ConsumerTemplate;
 import org.apache.camel.Exchange;
+import org.apache.camel.Produce;
 import org.apache.camel.ProducerTemplate;
 import org.apache.camel.quarkus.component.bean.model.Employee;
 
@@ -43,11 +47,16 @@ public class BeanResource {
     @Inject
     EagerAppScopedRouteBuilder routeBuilder;
 
-    @Inject
-    EndpointInjectBean endpointInjectBean;
+    public interface ProduceInterface {
+        String sayHello(String name);
+    }
+
+    @Produce("direct:produceInterface")
+    ProduceInterface produceInterface;
 
     @Inject
-    ConsumerTemplate endpointInjectConsumer;
+    @Named("collected-names")
+    Map<String, List<String>> collectedNames;
 
     @Path("/route/{route}")
     @POST
@@ -112,15 +121,6 @@ public class BeanResource {
         return BeanRoutes.CONFIGURE_COUNTER.get();
     }
 
-    @Path("/endpointInject")
-    @POST
-    @Consumes(MediaType.TEXT_PLAIN)
-    @Produces(MediaType.TEXT_PLAIN)
-    public String endpointInject(String payload) {
-        endpointInjectBean.forward(payload);
-        return endpointInjectConsumer.receiveBody("direct:endpointInject", 
10000, String.class);
-    }
-
     @Path("/employee/{route}")
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
@@ -142,4 +142,27 @@ public class BeanResource {
                 String.class);
     }
 
+    @Path("/produceInterface")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.TEXT_PLAIN)
+    public String produceInterface(String payload) {
+        produceInterface.sayHello(payload);
+        return awaitFirst("produceInterface");
+    }
+
+    String awaitFirst(String key) {
+        final List<String> list = collectedNames.get(key);
+        final long timeout = System.currentTimeMillis() + 10000;
+        do {
+            try {
+                Thread.sleep(50);
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                break;
+            }
+        } while (list.isEmpty() && System.currentTimeMillis() < timeout);
+        return list.get(0);
+    }
+
 }
diff --git 
a/integration-tests/bean/src/main/java/org/apache/camel/quarkus/component/bean/BeanRoutes.java
 
b/integration-tests/bean/src/main/java/org/apache/camel/quarkus/component/bean/BeanRoutes.java
index 1eb9b64..dfc9ed6 100644
--- 
a/integration-tests/bean/src/main/java/org/apache/camel/quarkus/component/bean/BeanRoutes.java
+++ 
b/integration-tests/bean/src/main/java/org/apache/camel/quarkus/component/bean/BeanRoutes.java
@@ -23,6 +23,10 @@ import java.util.Map;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.inject.Named;
+
 import io.quarkus.runtime.annotations.RegisterForReflection;
 import org.apache.camel.AsyncCallback;
 import org.apache.camel.AsyncProcessor;
@@ -37,10 +41,15 @@ import org.apache.camel.support.DefaultExchange;
 /**
  * A {@link RouteBuilder} instantiated by Camel (not by Arc).
  */
+@ApplicationScoped
 public class BeanRoutes extends RouteBuilder {
 
     static final AtomicInteger CONFIGURE_COUNTER = new AtomicInteger(0);
 
+    @Inject
+    @Named("collected-names")
+    Map<String, List<String>> collectedNames;
+
     @Override
     public void addRoutesToCamelContext(CamelContext context) throws Exception 
{
         CONFIGURE_COUNTER.incrementAndGet();
@@ -103,6 +112,9 @@ public class BeanRoutes extends RouteBuilder {
         from("direct:parameterTypes")
                 .to("bean:parametersBean?method=parameterTypes(String)");
 
+        from("direct:produceInterface")
+                .process(e -> 
collectedNames.get("produceInterface").add(e.getMessage().getBody(String.class)));
+
     }
 
     @SuppressWarnings("unchecked")
diff --git 
a/integration-tests/bean/src/main/java/org/apache/camel/quarkus/component/bean/method/Producers.java
 
b/integration-tests/bean/src/main/java/org/apache/camel/quarkus/component/bean/method/Producers.java
index 888785c..1d4f373 100644
--- 
a/integration-tests/bean/src/main/java/org/apache/camel/quarkus/component/bean/method/Producers.java
+++ 
b/integration-tests/bean/src/main/java/org/apache/camel/quarkus/component/bean/method/Producers.java
@@ -35,6 +35,7 @@ public class Producers {
         result.put("beanFromRegistryByName", new CopyOnWriteArrayList<>());
         result.put("beanByClassName", new CopyOnWriteArrayList<>());
         result.put("beanInstance", new CopyOnWriteArrayList<>());
+        result.put("produceInterface", new CopyOnWriteArrayList<>());
         return result;
     }
 }
diff --git 
a/integration-tests/bean/src/test/java/org/apache/camel/quarkus/component/bean/BeanTest.java
 
b/integration-tests/bean/src/test/java/org/apache/camel/quarkus/component/bean/BeanTest.java
index 540c3b2..1981f21 100644
--- 
a/integration-tests/bean/src/test/java/org/apache/camel/quarkus/component/bean/BeanTest.java
+++ 
b/integration-tests/bean/src/test/java/org/apache/camel/quarkus/component/bean/BeanTest.java
@@ -144,7 +144,7 @@ public class BeanTest {
                 .body(equalTo("wlpb-hello(wlpb-route-31wp,cflap-bean-31wp)"));
     }
 
-    @Disabled("https://github.com/apache/camel-quarkus/issues/2539";)
+    @Disabled("https://github.com/apache/camel-quarkus/issues/2580";)
     @Test
     public void consumeAnnotation() {
         RestAssured.given()
@@ -155,17 +155,6 @@ public class BeanTest {
                 .body(equalTo("Consumed foo"));
     }
 
-    @Disabled("https://github.com/apache/camel-quarkus/issues/2539";)
-    @Test
-    public void endpointInject() {
-        RestAssured.given()
-                .contentType(ContentType.TEXT)
-                .body("bar")
-                .post("/bean/endpointInject")
-                .then()
-                .body(equalTo("Sent to an @EndpointInject: bar"));
-    }
-
     @Test
     public void methodWithExchangeArg() {
         RestAssured.given()
@@ -226,4 +215,14 @@ public class BeanTest {
                 .body(equalTo("employeeAsString: Employee [firstName=Joe, 
lastName=Doe, seniority=senior]"));
     }
 
+    @Test
+    public void produceInterface() {
+        RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .body("xyz1234")
+                .post("/bean/produceInterface")
+                .then()
+                .body(equalTo("xyz1234"));
+    }
+
 }
diff --git 
a/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/CoreResource.java
 
b/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/CoreResource.java
index fe0e6b6..9d57144 100644
--- 
a/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/CoreResource.java
+++ 
b/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/CoreResource.java
@@ -40,7 +40,6 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
 import org.apache.camel.ExtendedCamelContext;
 import org.apache.camel.NoSuchLanguageException;
-import org.apache.camel.ProducerTemplate;
 import org.apache.camel.Route;
 import org.apache.camel.builder.LambdaRouteBuilder;
 import org.apache.camel.builder.TemplatedRouteBuilder;
@@ -55,7 +54,7 @@ import 
org.apache.camel.support.processor.DefaultExchangeFormatter;
 import org.apache.camel.support.startup.DefaultStartupStepRecorder;
 import org.apache.commons.io.IOUtils;
 
-@Path("/test")
+@Path("/core")
 @ApplicationScoped
 public class CoreResource {
     @Inject
@@ -63,9 +62,6 @@ public class CoreResource {
     @Inject
     CamelContext context;
 
-    @Inject
-    ProducerTemplate producerTemplate;
-
     @Path("/registry/log/exchange-formatter")
     @GET
     @Produces(MediaType.APPLICATION_JSON)
@@ -282,4 +278,5 @@ public class CoreResource {
     public AnnotatedMyPair fromStringToAnnotatedMyPair(String input) {
         return context.getTypeConverter().convertTo(AnnotatedMyPair.class, 
input);
     }
+
 }
diff --git 
a/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/annotations/CoreAnnotationsResource.java
 
b/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/annotations/CoreAnnotationsResource.java
new file mode 100644
index 0000000..2813a2b
--- /dev/null
+++ 
b/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/annotations/CoreAnnotationsResource.java
@@ -0,0 +1,123 @@
+/*
+ * 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.annotations;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.FluentProducerTemplate;
+import org.apache.camel.Produce;
+import org.apache.camel.ProducerTemplate;
+
+@Path("/core/annotations")
+@ApplicationScoped
+public class CoreAnnotationsResource {
+
+    @Inject
+    ProducerTemplate producerTemplate;
+
+    @EndpointInject("direct:endpointInjectTemplate")
+    ProducerTemplate endpointInjectTemplateProducer;
+
+    @EndpointInject("direct:endpointInjectFluentTemplate")
+    FluentProducerTemplate endpointInjectFluentTemplateProducer;
+
+    @Produce("direct:produceProducer")
+    ProducerTemplate produceProducer;
+
+    @Produce("direct:produceProducerFluent")
+    FluentProducerTemplate produceProducerFluent;
+
+    @Inject
+    @Named("results")
+    Map<String, List<String>> results;
+
+    @Path("/endpointInjectTemplate")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.TEXT_PLAIN)
+    public String endpointInjectTemplate(String payload) {
+        endpointInjectTemplateProducer.sendBody("Sent to an @EndpointInject: " 
+ payload);
+        return awaitFirst("endpointInjectTemplate");
+    }
+
+    @Path("/endpointInjectFluentTemplate")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.TEXT_PLAIN)
+    public String endpointInjectFluentTemplate(String payload) {
+        endpointInjectFluentTemplateProducer
+                .withBody("Sent to an @EndpointInject fluent: " + payload)
+                .send();
+        return awaitFirst("endpointInjectFluentTemplate");
+    }
+
+    @Path("/endpointInjectDirect/{index}")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.TEXT_PLAIN)
+    public String endpointInjectDirect(String payload, @PathParam("index") 
String index) {
+        producerTemplate.sendBody("direct:endpointInjectDirectStart" + index, 
payload);
+        return awaitFirst("endpointInjectDirect" + index);
+    }
+
+    @Path("/produceProducer")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.TEXT_PLAIN)
+    public String produceProducer(String payload) {
+        produceProducer.sendBody("Sent to an @Produce: " + payload);
+        return awaitFirst("produceProducer");
+    }
+
+    @Path("/produceProducerFluent")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.TEXT_PLAIN)
+    public String produceProducerFluent(String payload) {
+        produceProducerFluent
+                .withBody("Sent to an @Produce fluent: " + payload)
+                .send();
+        return awaitFirst("produceProducerFluent");
+    }
+
+    String awaitFirst(String key) {
+        final List<String> list = results.get(key);
+        final long timeout = System.currentTimeMillis() + 10000;
+        do {
+            try {
+                Thread.sleep(50);
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                break;
+            }
+        } while (list.isEmpty() && System.currentTimeMillis() < timeout);
+        return list.get(0);
+    }
+
+}
diff --git 
a/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/annotations/CoreAnnotationsRoutes.java
 
b/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/annotations/CoreAnnotationsRoutes.java
new file mode 100644
index 0000000..c2fb864
--- /dev/null
+++ 
b/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/annotations/CoreAnnotationsRoutes.java
@@ -0,0 +1,86 @@
+/*
+ * 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.annotations;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Produces;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.direct.DirectEndpoint;
+
+@ApplicationScoped
+public class CoreAnnotationsRoutes extends RouteBuilder {
+
+    @Inject
+    @Named("results")
+    Map<String, List<String>> results;
+
+    @EndpointInject("direct:endpointInjectDirect1")
+    DirectEndpoint endpointInjectDirect1;
+    @EndpointInject("direct:endpointInjectDirect2")
+    DirectEndpoint endpointInjectDirect2;
+
+    @Override
+    public void configure() {
+
+        from("direct:endpointInjectTemplate")
+                .process(e -> 
results.get("endpointInjectTemplate").add(e.getMessage().getBody(String.class)));
+
+        from("direct:endpointInjectFluentTemplate")
+                .process(e -> 
results.get("endpointInjectFluentTemplate").add(e.getMessage().getBody(String.class)));
+
+        from("direct:produceProducer")
+                .process(e -> 
results.get("produceProducer").add(e.getMessage().getBody(String.class)));
+
+        from("direct:produceProducerFluent")
+                .process(e -> 
results.get("produceProducerFluent").add(e.getMessage().getBody(String.class)));
+
+        from("direct:endpointInjectDirectStart1")
+                .to(endpointInjectDirect1);
+        from("direct:endpointInjectDirect1")
+                .process(e -> 
results.get("endpointInjectDirect1").add(e.getMessage().getBody(String.class)));
+
+        from("direct:endpointInjectDirectStart2")
+                .to(endpointInjectDirect2);
+        from("direct:endpointInjectDirect2")
+                .process(e -> 
results.get("endpointInjectDirect2").add(e.getMessage().getBody(String.class)));
+
+    }
+
+    @Produces
+    @ApplicationScoped
+    @Named("results")
+    public Map<String, List<String>> results() {
+        Map<String, List<String>> result = new HashMap<>();
+        result.put("endpointInjectTemplate", new CopyOnWriteArrayList<>());
+        result.put("endpointInjectFluentTemplate", new 
CopyOnWriteArrayList<>());
+        result.put("endpointInjectDirect1", new CopyOnWriteArrayList<>());
+        result.put("endpointInjectDirect2", new CopyOnWriteArrayList<>());
+        result.put("produceProducer", new CopyOnWriteArrayList<>());
+        result.put("produceProducerFluent", new CopyOnWriteArrayList<>());
+        return result;
+    }
+
+}
diff --git 
a/integration-tests/bean/src/main/java/org/apache/camel/quarkus/component/bean/EndpointInjectBean.java
 
b/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CoreAnnotationsIT.java
similarity index 61%
rename from 
integration-tests/bean/src/main/java/org/apache/camel/quarkus/component/bean/EndpointInjectBean.java
rename to 
integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CoreAnnotationsIT.java
index aa62160..d8b74d0 100644
--- 
a/integration-tests/bean/src/main/java/org/apache/camel/quarkus/component/bean/EndpointInjectBean.java
+++ 
b/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CoreAnnotationsIT.java
@@ -14,23 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.quarkus.component.bean;
+package org.apache.camel.quarkus.core;
 
-import javax.enterprise.context.ApplicationScoped;
+import io.quarkus.test.junit.NativeImageTest;
 
-import io.quarkus.runtime.annotations.RegisterForReflection;
-import org.apache.camel.EndpointInject;
-import org.apache.camel.ProducerTemplate;
-
-@ApplicationScoped
-@RegisterForReflection
-public class EndpointInjectBean {
-
-    @EndpointInject("direct:endpointInject")
-    ProducerTemplate producer;
-
-    public void forward(String payload) {
-        producer.sendBody("Sent to an @EndpointInject: " + payload);
-    }
+@NativeImageTest
+public class CoreAnnotationsIT extends CoreAnnotationsTest {
 
 }
diff --git 
a/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CoreAnnotationsTest.java
 
b/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CoreAnnotationsTest.java
new file mode 100644
index 0000000..3ff2125
--- /dev/null
+++ 
b/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CoreAnnotationsTest.java
@@ -0,0 +1,88 @@
+/*
+ * 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 io.quarkus.test.junit.QuarkusTest;
+import io.restassured.RestAssured;
+import io.restassured.http.ContentType;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.Matchers.equalTo;
+
+@QuarkusTest
+public class CoreAnnotationsTest {
+
+    @Test
+    public void endpointInjectFluentTemplate() {
+        RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .body("baz")
+                .post("/core/annotations/endpointInjectFluentTemplate")
+                .then()
+                .body(equalTo("Sent to an @EndpointInject fluent: baz"));
+    }
+
+    @Test
+    public void endpointInjectDirect() {
+        RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .body("fgh1")
+                .post("/core/annotations/endpointInjectDirect/1")
+                .then()
+                .body(equalTo("fgh1"));
+
+        /* Make sure that qualifying via 
@EndpointInject("direct:endpointInjectDirect2") works
+         * If this fails, it means that the container injects only based on 
type */
+        RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .body("fgh2")
+                .post("/core/annotations/endpointInjectDirect/2")
+                .then()
+                .body(equalTo("fgh2"));
+    }
+
+    @Test
+    public void endpointInjectTemplate() {
+        RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .body("bar")
+                .post("/core/annotations/endpointInjectTemplate")
+                .then()
+                .body(equalTo("Sent to an @EndpointInject: bar"));
+    }
+
+    @Test
+    public void produceProducerFluent() {
+        RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .body("cde")
+                .post("/core/annotations/produceProducerFluent")
+                .then()
+                .body(equalTo("Sent to an @Produce fluent: cde"));
+    }
+
+    @Test
+    public void produceProducer() {
+        RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .body("abc")
+                .post("/core/annotations/produceProducer")
+                .then()
+                .body(equalTo("Sent to an @Produce: abc"));
+    }
+
+}
diff --git 
a/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CoreIT.java
 
b/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CoreIT.java
index a631c88..fbcc377 100644
--- 
a/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CoreIT.java
+++ 
b/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CoreIT.java
@@ -29,24 +29,24 @@ public class CoreIT extends CoreTest {
 
     @Test
     public void nonExistentResourceCouldNotBeLoadedFromNativeExecutable() {
-        
RestAssured.when().get("/test/resources/not-exist.txt").then().assertThat().statusCode(204);
+        
RestAssured.when().get("/core/resources/not-exist.txt").then().assertThat().statusCode(204);
     }
 
     @Test
     public void 
resourceMatchingExcludedPatternOnlyCouldNotBeLoadedFromNativeExecutable() {
-        
RestAssured.when().get("/test/resources/exclude-pattern-folder/excluded.txt").then().assertThat()
+        
RestAssured.when().get("/core/resources/exclude-pattern-folder/excluded.txt").then().assertThat()
                 .statusCode(204);
     }
 
     @Test
     public void 
resourceMatchingIncludeAndExcludedPatternCouldNotBeLoadedFromNativeExecutable() 
{
-        
RestAssured.when().get("/test/resources/include-pattern-folder/excluded.txt").then().assertThat()
+        
RestAssured.when().get("/core/resources/include-pattern-folder/excluded.txt").then().assertThat()
                 .statusCode(204);
     }
 
     @Test
     public void 
resourceMatchingIncludePatternOnlyCouldBeLoadedFromNativeExecutable() {
-        String response = 
RestAssured.when().get("/test/resources/include-pattern-folder/included.txt").then()
+        String response = 
RestAssured.when().get("/core/resources/include-pattern-folder/included.txt").then()
                 .assertThat().statusCode(200).extract().asString();
         assertNotNull(response);
         assertTrue(response.endsWith("MATCH include-patterns BUT NOT 
exclude-patterns"), response);
@@ -54,7 +54,7 @@ public class CoreIT extends CoreTest {
 
     @Test
     public void 
resourceMatchingNoPatternCouldNotBeLoadedFromNativeExecutable() {
-        
RestAssured.when().get("/test/resources/no-pattern-folder/excluded.properties.txt").then().assertThat()
+        
RestAssured.when().get("/core/resources/no-pattern-folder/excluded.properties.txt").then().assertThat()
                 .statusCode(204);
     }
 
@@ -62,7 +62,7 @@ public class CoreIT extends CoreTest {
     void reflectiveMethod() {
         RestAssured.when()
                 .get(
-                        
"/test/reflection/{className}/method/{methodName}/{value}",
+                        
"/core/reflection/{className}/method/{methodName}/{value}",
                         "org.apache.commons.lang3.tuple.MutableTriple",
                         "setLeft",
                         "Kermit")
@@ -75,7 +75,7 @@ public class CoreIT extends CoreTest {
     void reflectiveField() {
         RestAssured.when()
                 .get(
-                        
"/test/reflection/{className}/field/{fieldName}/{value}",
+                        
"/core/reflection/{className}/field/{fieldName}/{value}",
                         "org.apache.commons.lang3.tuple.MutableTriple",
                         "left",
                         "Joe")
diff --git 
a/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CoreTest.java
 
b/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CoreTest.java
index dbbb0cb..f94e9fc 100644
--- 
a/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CoreTest.java
+++ 
b/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CoreTest.java
@@ -38,29 +38,29 @@ public class CoreTest {
 
     @Test
     public void testContainerLookupFromRegistry() {
-        
RestAssured.when().get("/test/registry/lookup-registry").then().body(is("true"));
-        
RestAssured.when().get("/test/registry/lookup-context").then().body(is("true"));
+        
RestAssured.when().get("/core/registry/lookup-registry").then().body(is("true"));
+        
RestAssured.when().get("/core/registry/lookup-context").then().body(is("true"));
     }
 
     @Test
     public void testLookupRoutes() {
-        
RestAssured.when().get("/test/routes/lookup-routes").then().body(containsString("bar"),
 containsString("timer"));
+        
RestAssured.when().get("/core/routes/lookup-routes").then().body(containsString("bar"),
 containsString("timer"));
     }
 
     @Test
     public void testRouteTemplate() {
-        
RestAssured.when().get("/test/routes/template/myTemplate/World").then().body(is("Hello
 World"));
-        
RestAssured.when().get("/test/routes/template/myTemplate/Earth").then().body(is("Hello
 Earth"));
+        
RestAssured.when().get("/core/routes/template/myTemplate/World").then().body(is("Hello
 World"));
+        
RestAssured.when().get("/core/routes/template/myTemplate/Earth").then().body(is("Hello
 Earth"));
     }
 
     @Test
     public void testCamelContextAwareRegistryBeansInitialized() {
-        
RestAssured.when().get("/test/registry/camel-context-aware/initialized").then().body(is("true"));
+        
RestAssured.when().get("/core/registry/camel-context-aware/initialized").then().body(is("true"));
     }
 
     @Test
     public void testCamelBeanBuildItem() {
-        Response response = 
RestAssured.get("/test/registry/log/exchange-formatter").andReturn();
+        Response response = 
RestAssured.get("/core/registry/log/exchange-formatter").andReturn();
 
         assertEquals(HttpURLConnection.HTTP_OK, response.getStatusCode());
         assertTrue(response.jsonPath().getBoolean("show-all"));
@@ -69,38 +69,38 @@ public class CoreTest {
 
     @Test
     public void testCamelContextVersion() {
-        RestAssured.when().get("/test/context/version").then().body(not(""));
+        RestAssured.when().get("/core/context/version").then().body(not(""));
     }
 
     @Test
     public void testResolveLanguages() {
-        
RestAssured.when().get("/test/language/simple").then().body(is("true"));
-        
RestAssured.when().get("/test/language/undefined").then().body(is("false"));
+        
RestAssured.when().get("/core/language/simple").then().body(is("true"));
+        
RestAssured.when().get("/core/language/undefined").then().body(is("false"));
     }
 
     @Test
     public void testCatalogComponent() throws IOException {
-        
RestAssured.when().get("/test/catalog/component/timer").then().body(not(emptyOrNullString()));
-        
RestAssured.when().get("/test/catalog/language/simple").then().statusCode(500).body(is(
+        
RestAssured.when().get("/core/catalog/component/timer").then().body(not(emptyOrNullString()));
+        
RestAssured.when().get("/core/catalog/language/simple").then().statusCode(500).body(is(
                 "RuntimeException: Accessing language JSON schemas was 
disabled via quarkus.camel.runtime-catalog.languages = false"));
     }
 
     @Test
     public void testAdaptContext() {
-        
RestAssured.when().get("/test/adapt/model-camel-context").then().body(is("true"));
-        
RestAssured.when().get("/test/adapt/extended-camel-context").then().body(is("true"));
+        
RestAssured.when().get("/core/adapt/model-camel-context").then().body(is("true"));
+        
RestAssured.when().get("/core/adapt/extended-camel-context").then().body(is("true"));
     }
 
     @Test
     public void testLRUCacheFactory() {
-        
RestAssured.when().get("/test/lru-cache-factory").then().body(is(DefaultLRUCacheFactory.class.getName()));
+        
RestAssured.when().get("/core/lru-cache-factory").then().body(is(DefaultLRUCacheFactory.class.getName()));
     }
 
     @Test
     void reflectiveMethod() {
         RestAssured.when()
                 .get(
-                        
"/test/reflection/{className}/method/{methodName}/{value}",
+                        
"/core/reflection/{className}/method/{methodName}/{value}",
                         "org.apache.commons.lang3.tuple.MutablePair",
                         "setLeft",
                         "Kermit")
@@ -113,7 +113,7 @@ public class CoreTest {
     void reflectiveField() {
         RestAssured.when()
                 .get(
-                        
"/test/reflection/{className}/field/{fieldName}/{value}",
+                        
"/core/reflection/{className}/field/{fieldName}/{value}",
                         "org.apache.commons.lang3.tuple.MutablePair",
                         "left",
                         "Joe")
@@ -124,12 +124,12 @@ public class CoreTest {
 
     @Test
     void testDefaultHeadersMapFactoryConfigured() {
-        
RestAssured.when().get("/test/headersmap-factory").then().body(is("true"));
+        
RestAssured.when().get("/core/headersmap-factory").then().body(is("true"));
     }
 
     @Test
     void testStartupStepRecorder() {
-        
RestAssured.when().get("/test/startup-step-recorder").then().body(is("true"));
+        
RestAssured.when().get("/core/startup-step-recorder").then().body(is("true"));
     }
 
     @Test
@@ -137,7 +137,7 @@ public class CoreTest {
         RestAssured.given()
                 .contentType(ContentType.TEXT).body("a:b")
                 .accept(MediaType.APPLICATION_JSON)
-                .post("/test/converter/annotatedMyPair")
+                .post("/core/converter/annotatedMyPair")
                 .then()
                 .statusCode(200)
                 .body("key", is("a"), "annotatedValue", is("b"));

Reply via email to