This is an automated email from the ASF dual-hosted git repository. jamesnetherton pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
commit 6f4228848ef68eff290ef735d8552dcc23cf7266 Author: James Netherton <jamesnether...@gmail.com> AuthorDate: Fri Jan 27 11:08:14 2023 +0000 Support registry lookups by name for beans annotated with io.smallrye.common.annotation.Identifier Fixes #4374 --- .../CamelBeanLookupWithIdentifierTest.java | 99 ++++++++++++++++++++++ .../camel/quarkus/core/RuntimeBeanRepository.java | 8 +- .../camel/quarkus/component/bean/BeanRoutes.java | 3 + .../quarkus/component/bean/IdentifiedBean.java | 37 ++++++++ .../camel/quarkus/component/bean/BeanTest.java | 13 ++- 5 files changed, 155 insertions(+), 5 deletions(-) diff --git a/extensions-core/core/deployment/src/test/java/org/apache/camel/quarkus/core/deployment/CamelBeanLookupWithIdentifierTest.java b/extensions-core/core/deployment/src/test/java/org/apache/camel/quarkus/core/deployment/CamelBeanLookupWithIdentifierTest.java new file mode 100644 index 0000000000..6d173c5fd9 --- /dev/null +++ b/extensions-core/core/deployment/src/test/java/org/apache/camel/quarkus/core/deployment/CamelBeanLookupWithIdentifierTest.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.quarkus.core.deployment; + +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.util.Properties; + +import javax.enterprise.inject.Produces; +import javax.inject.Inject; + +import io.quarkus.arc.Unremovable; +import io.quarkus.test.QuarkusUnitTest; +import io.smallrye.common.annotation.Identifier; +import org.apache.camel.CamelContext; +import org.apache.camel.FluentProducerTemplate; +import org.apache.camel.Produce; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.support.CamelContextHelper; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.Asset; +import org.jboss.shrinkwrap.api.asset.StringAsset; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class CamelBeanLookupWithIdentifierTest { + + @RegisterExtension + static final QuarkusUnitTest CONFIG = new QuarkusUnitTest() + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class) + .addAsResource(applicationProperties(), "application.properties")); + + public static Asset applicationProperties() { + Writer writer = new StringWriter(); + + Properties props = new Properties(); + props.setProperty("quarkus.banner.enabled", "false"); + + try { + props.store(writer, ""); + } catch (IOException e) { + throw new RuntimeException(e); + } + + return new StringAsset(writer.toString()); + } + + @Inject + CamelContext context; + + @Produce("direct:start") + FluentProducerTemplate template; + + @Test + public void beanLookupWithIdentifierAnnotation() { + MyIdentifiedBean bean = CamelContextHelper.lookup(context, "my-identifier", MyIdentifiedBean.class); + assertNotNull(bean); + assertEquals("Hello World", template.request(String.class)); + } + + @Produces + @Unremovable + @Identifier("my-identifier") + public MyIdentifiedBean createIdentifiedBean() { + return new MyIdentifiedBean(); + } + + public static class Routes extends RouteBuilder { + @Override + public void configure() throws Exception { + from("direct:start").bean("my-identifier"); + } + } + + public static class MyIdentifiedBean { + public String greet() { + return "Hello World"; + } + } +} diff --git a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/RuntimeBeanRepository.java b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/RuntimeBeanRepository.java index 6e49b5035d..af4ba0310c 100644 --- a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/RuntimeBeanRepository.java +++ b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/RuntimeBeanRepository.java @@ -30,6 +30,7 @@ import javax.enterprise.inject.spi.BeanManager; import io.quarkus.arc.Arc; import io.quarkus.arc.ArcContainer; +import io.smallrye.common.annotation.Identifier; import org.apache.camel.spi.BeanRepository; public final class RuntimeBeanRepository implements BeanRepository { @@ -72,7 +73,12 @@ public final class RuntimeBeanRepository implements BeanRepository { } private static <T> Optional<T> getReferenceByName(BeanManager manager, String name, Class<T> type) { - return Optional.ofNullable(manager.resolve(manager.getBeans(name))).map(bean -> getReference(manager, type, bean)); + Set<Bean<?>> beans = manager.getBeans(name); + if (beans.isEmpty()) { + // Fallback to SmallRye @Identifier + beans = manager.getBeans(type, Identifier.Literal.of(name)); + } + return Optional.ofNullable(manager.resolve(beans)).map(bean -> getReference(manager, type, bean)); } private static <T> T getReference(BeanManager manager, Class<T> type, Bean<?> bean) { diff --git a/integration-test-groups/foundation/bean/src/main/java/org/apache/camel/quarkus/component/bean/BeanRoutes.java b/integration-test-groups/foundation/bean/src/main/java/org/apache/camel/quarkus/component/bean/BeanRoutes.java index be68aad51c..71128a9f7d 100644 --- a/integration-test-groups/foundation/bean/src/main/java/org/apache/camel/quarkus/component/bean/BeanRoutes.java +++ b/integration-test-groups/foundation/bean/src/main/java/org/apache/camel/quarkus/component/bean/BeanRoutes.java @@ -74,6 +74,9 @@ public class BeanRoutes extends RouteBuilder { from("direct:named") .to("bean:namedBean?method=hello"); + from("direct:identified") + .to("bean:identifiedBean?method=hello"); + from("direct:method") .bean(MyBean.class, "sayHello"); diff --git a/integration-test-groups/foundation/bean/src/main/java/org/apache/camel/quarkus/component/bean/IdentifiedBean.java b/integration-test-groups/foundation/bean/src/main/java/org/apache/camel/quarkus/component/bean/IdentifiedBean.java new file mode 100644 index 0000000000..828d8533ae --- /dev/null +++ b/integration-test-groups/foundation/bean/src/main/java/org/apache/camel/quarkus/component/bean/IdentifiedBean.java @@ -0,0 +1,37 @@ +/* + * 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.component.bean; + +import javax.enterprise.context.ApplicationScoped; + +import io.quarkus.arc.Unremovable; +import io.quarkus.runtime.annotations.RegisterForReflection; +import io.smallrye.common.annotation.Identifier; + +/** + * A bean referenced from a route (and from nowhere else) by its identifier. + */ +@ApplicationScoped +@Identifier("identifiedBean") +@Unremovable +@RegisterForReflection +public class IdentifiedBean { + + public String hello(String name) { + return "Hello " + name + " from the IdentifiedBean"; + } +} diff --git a/integration-test-groups/foundation/bean/src/test/java/org/apache/camel/quarkus/component/bean/BeanTest.java b/integration-test-groups/foundation/bean/src/test/java/org/apache/camel/quarkus/component/bean/BeanTest.java index 5b6d0bf38b..5e61dc0d55 100644 --- a/integration-test-groups/foundation/bean/src/test/java/org/apache/camel/quarkus/component/bean/BeanTest.java +++ b/integration-test-groups/foundation/bean/src/test/java/org/apache/camel/quarkus/component/bean/BeanTest.java @@ -20,7 +20,10 @@ import io.quarkus.test.junit.QuarkusTest; import io.restassured.RestAssured; import io.restassured.http.ContentType; import org.apache.camel.quarkus.component.bean.model.Employee; +import org.apache.camel.util.StringHelper; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.containsString; @@ -45,14 +48,16 @@ public class BeanTest { .body(equalTo("1")); } - @Test - public void named() { + @ParameterizedTest + @ValueSource(strings = { "named", "identified" }) + public void named(String routeName) { + String beanName = StringHelper.capitalize(routeName) + "Bean"; RestAssured.given() .contentType(ContentType.TEXT) .body("Kermit") - .post("/bean/route/named") + .post("/bean/route/" + routeName) .then() - .body(equalTo("Hello Kermit from the NamedBean")); + .body(equalTo("Hello Kermit from the " + beanName)); } @Test