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

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

commit 439350c869709a51c0207d1a1351bd148401afb2
Author: Zheng Feng <zh.f...@gmail.com>
AuthorDate: Mon Apr 14 23:39:06 2025 +0800

    Fix #7254 to support named entityManagerFactory in camel-quarkus-jpa
---
 .../camel/quarkus/core/RuntimeBeanRepository.java  |  12 ++
 .../component/jpa/deployment/JpaProcessor.java     |  25 ++++
 .../quarkus/component/jpa/CamelJpaRecorder.java    |  16 +++
 .../camel/quarkus/component/jpa/it/JpaRoute.java   |   2 +
 .../jpa/src/main/resources/application.properties  |   8 +-
 .../camel/quarkus/component/jpa/it/JpaTest.java    | 149 +--------------------
 .../jpa/it/{JpaTest.java => JpaTestBase.java}      |   4 +-
 .../quarkus/component/jpa/it/NamedJpaTest.java     |  18 +--
 .../component/jpa/it/NamedJpaTestProfile.java      |  18 ++-
 9 files changed, 77 insertions(+), 175 deletions(-)

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 4522183835..2b860c15b9 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
@@ -25,6 +25,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import io.quarkus.arc.Arc;
 import io.quarkus.arc.ArcContainer;
@@ -80,6 +81,17 @@ public final class RuntimeBeanRepository implements 
BeanRepository {
     private static <T> Optional<T> getReferenceByName(BeanManager manager, 
String name, Class<T> type) {
         Set<Bean<?>> beans = manager.getBeans(name);
 
+        // If it is a Synthetic bean, it should match with type
+        beans = beans.stream()
+                .filter(bean -> {
+                    if (bean instanceof InjectableBean injectableBean) {
+                        return 
!injectableBean.getKind().equals(InjectableBean.Kind.SYNTHETIC)
+                                || bean.getTypes().contains(type);
+                    } else {
+                        return true;
+                    }
+                }).collect(Collectors.toSet());
+
         if (beans.isEmpty()) {
             // Fallback to searching explicitly with NamedLiteral
             beans = manager.getBeans(type, NamedLiteral.of(name));
diff --git 
a/extensions/jpa/deployment/src/main/java/org/apache/camel/quarkus/component/jpa/deployment/JpaProcessor.java
 
b/extensions/jpa/deployment/src/main/java/org/apache/camel/quarkus/component/jpa/deployment/JpaProcessor.java
index adfc8405b8..4ec977b19d 100644
--- 
a/extensions/jpa/deployment/src/main/java/org/apache/camel/quarkus/component/jpa/deployment/JpaProcessor.java
+++ 
b/extensions/jpa/deployment/src/main/java/org/apache/camel/quarkus/component/jpa/deployment/JpaProcessor.java
@@ -16,15 +16,20 @@
  */
 package org.apache.camel.quarkus.component.jpa.deployment;
 
+import java.util.List;
+
 import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
 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.FeatureBuildItem;
+import io.quarkus.hibernate.orm.deployment.PersistenceUnitDescriptorBuildItem;
+import jakarta.persistence.EntityManagerFactory;
 import org.apache.camel.component.jpa.JpaComponent;
 import org.apache.camel.quarkus.component.jpa.CamelJpaProducer;
 import org.apache.camel.quarkus.component.jpa.CamelJpaRecorder;
+import 
org.apache.camel.quarkus.core.deployment.spi.CamelBeanQualifierResolverBuildItem;
 import org.apache.camel.quarkus.core.deployment.spi.CamelRuntimeBeanBuildItem;
 
 class JpaProcessor {
@@ -50,4 +55,24 @@ class JpaProcessor {
                         JpaComponent.class.getName(),
                         recorder.createJpaComponent()));
     }
+
+    @Record(ExecutionTime.STATIC_INIT)
+    @BuildStep
+    void registerPersistenceUnitCamelBeanQualifierResolver(
+            List<PersistenceUnitDescriptorBuildItem> 
persistenceUnitDescriptors,
+            BuildProducer<CamelBeanQualifierResolverBuildItem> 
camelBeanQualifierResolver,
+            CamelJpaRecorder recorder) {
+        // If there are multiple persistence unit configs, then users need to 
explicitly state which one to use
+        // via their component / endpoint configuration. Otherwise if there is 
just 1, and it is not the default,
+        // we can create a resolver for PersistenceUnitLiteral and make named 
PersistenceUnit autowiring work as expected
+        if (persistenceUnitDescriptors.size() == 1) {
+            PersistenceUnitDescriptorBuildItem persistenceUnitDescriptor = 
persistenceUnitDescriptors.get(0);
+            if 
(!persistenceUnitDescriptor.getPersistenceUnitName().equals("<default>")) {
+                CamelBeanQualifierResolverBuildItem beanQualifierResolver = 
new CamelBeanQualifierResolverBuildItem(
+                        EntityManagerFactory.class,
+                        
recorder.createPersistenceUnitQualifierResolver(persistenceUnitDescriptor.getPersistenceUnitName()));
+                camelBeanQualifierResolver.produce(beanQualifierResolver);
+            }
+        }
+    }
 }
diff --git 
a/extensions/jpa/runtime/src/main/java/org/apache/camel/quarkus/component/jpa/CamelJpaRecorder.java
 
b/extensions/jpa/runtime/src/main/java/org/apache/camel/quarkus/component/jpa/CamelJpaRecorder.java
index 658d5424ee..eb96ba41d3 100644
--- 
a/extensions/jpa/runtime/src/main/java/org/apache/camel/quarkus/component/jpa/CamelJpaRecorder.java
+++ 
b/extensions/jpa/runtime/src/main/java/org/apache/camel/quarkus/component/jpa/CamelJpaRecorder.java
@@ -16,9 +16,13 @@
  */
 package org.apache.camel.quarkus.component.jpa;
 
+import java.lang.annotation.Annotation;
+
+import io.quarkus.hibernate.orm.PersistenceUnit;
 import io.quarkus.runtime.RuntimeValue;
 import io.quarkus.runtime.annotations.Recorder;
 import org.apache.camel.component.jpa.JpaComponent;
+import org.apache.camel.quarkus.core.CamelBeanQualifierResolver;
 
 @Recorder
 public class CamelJpaRecorder {
@@ -28,4 +32,16 @@ public class CamelJpaRecorder {
         component.setTransactionStrategy(new QuarkusTransactionStrategy());
         return new RuntimeValue<>(component);
     }
+
+    public RuntimeValue<CamelBeanQualifierResolver> 
createPersistenceUnitQualifierResolver(String persistenceUnitName) {
+        return new RuntimeValue<>(new CamelBeanQualifierResolver() {
+            final PersistenceUnit.PersistenceUnitLiteral 
persistenceUnitLiteral = new PersistenceUnit.PersistenceUnitLiteral(
+                    persistenceUnitName);
+
+            @Override
+            public Annotation[] resolveQualifiers() {
+                return new Annotation[] { persistenceUnitLiteral };
+            }
+        });
+    }
 }
diff --git 
a/integration-tests/jpa/src/main/java/org/apache/camel/quarkus/component/jpa/it/JpaRoute.java
 
b/integration-tests/jpa/src/main/java/org/apache/camel/quarkus/component/jpa/it/JpaRoute.java
index 46f5c1e084..85b396c3af 100644
--- 
a/integration-tests/jpa/src/main/java/org/apache/camel/quarkus/component/jpa/it/JpaRoute.java
+++ 
b/integration-tests/jpa/src/main/java/org/apache/camel/quarkus/component/jpa/it/JpaRoute.java
@@ -20,6 +20,7 @@ import java.util.Collections;
 
 import jakarta.enterprise.context.ApplicationScoped;
 import jakarta.inject.Inject;
+import jakarta.inject.Named;
 import jakarta.persistence.EntityManagerFactory;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.jpa.TransactionStrategy;
@@ -30,6 +31,7 @@ import org.apache.camel.quarkus.component.jpa.it.model.Fruit;
 public class JpaRoute extends RouteBuilder {
 
     @Inject
+    @Named("test")
     EntityManagerFactory entityManagerFactory;
 
     @Inject
diff --git a/integration-tests/jpa/src/main/resources/application.properties 
b/integration-tests/jpa/src/main/resources/application.properties
index 81158c974b..df88312f05 100644
--- a/integration-tests/jpa/src/main/resources/application.properties
+++ b/integration-tests/jpa/src/main/resources/application.properties
@@ -15,6 +15,10 @@
 ## limitations under the License.
 ## ---------------------------------------------------------------------------
 quarkus.datasource.db-kind=${cq.sqlJdbcKind:h2}
-quarkus.datasource.jdbc.max-size=8
 
-quarkus.hibernate-orm.database.generation=drop-and-create
+quarkus.datasource."test".db-kind=${cq.sqlJdbcKind:h2}
+quarkus.datasource."test".jdbc.max-size=8
+
+quarkus.hibernate-orm."test".packages=org.apache.camel.quarkus.component.jpa.it.model,org.apache.camel.processor.idempotent.jpa
+quarkus.hibernate-orm."test".datasource=test
+quarkus.hibernate-orm."test".database.generation=drop-and-create
diff --git 
a/integration-tests/jpa/src/test/java/org/apache/camel/quarkus/component/jpa/it/JpaTest.java
 
b/integration-tests/jpa/src/test/java/org/apache/camel/quarkus/component/jpa/it/JpaTest.java
index 5bfd83e592..4b284ad2b7 100644
--- 
a/integration-tests/jpa/src/test/java/org/apache/camel/quarkus/component/jpa/it/JpaTest.java
+++ 
b/integration-tests/jpa/src/test/java/org/apache/camel/quarkus/component/jpa/it/JpaTest.java
@@ -16,155 +16,8 @@
  */
 package org.apache.camel.quarkus.component.jpa.it;
 
-import java.util.concurrent.TimeUnit;
-import java.util.stream.IntStream;
-
 import io.quarkus.test.junit.QuarkusTest;
-import io.restassured.RestAssured;
-import io.restassured.http.ContentType;
-import jakarta.json.bind.JsonbBuilder;
-import org.apache.camel.quarkus.component.jpa.it.model.Fruit;
-import org.eclipse.microprofile.config.Config;
-import org.eclipse.microprofile.config.ConfigProvider;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-
-import static org.awaitility.Awaitility.await;
-import static org.hamcrest.Matchers.contains;
-import static org.hamcrest.Matchers.containsInAnyOrder;
-import static org.hamcrest.Matchers.greaterThanOrEqualTo;
-import static org.hamcrest.Matchers.hasItems;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.notNullValue;
 
 @QuarkusTest
-class JpaTest {
-
-    static final String[] FRUITS = new String[] { "Orange", "Lemon", "Plum" };
-
-    @BeforeAll
-    public static void storeFruits() {
-        final Config config = ConfigProvider.getConfig();
-        int port = config.getValue("quarkus.http.test-port", int.class);
-        RestAssured.port = port;
-        for (String fruit : FRUITS) {
-            RestAssured.given()
-                    .contentType(ContentType.JSON)
-                    .body(JsonbBuilder.create().toJson(new Fruit(fruit)))
-                    .post("/jpa/fruit")
-                    .then()
-                    .statusCode(201);
-        }
-    }
-
-    @Test
-    public void testProducerQuery() {
-        RestAssured.get("/jpa/fruit")
-                .then()
-                .statusCode(200)
-                .body("name", containsInAnyOrder(FRUITS));
-    }
-
-    @Test
-    public void testProducerNamedQuery() {
-        RestAssured.get("/jpa/fruit/named/" + FRUITS[0])
-                .then()
-                .statusCode(200)
-                .body("name", contains(FRUITS[0]));
-    }
-
-    @Test
-    public void testProducerNativeQuery() {
-        RestAssured.get("/jpa/fruit/native/2")
-                .then()
-                .statusCode(200)
-                .body("name", contains(FRUITS[1]));
-    }
-
-    @Test
-    public void testConsumer() {
-        IntStream.range(1, 3).parallel().forEach((id) -> {
-            await().atMost(10L, TimeUnit.SECONDS).until(() -> 
findFruit(id).getProcessed());
-        });
-
-        RestAssured.get("/jpa/mock/processed")
-                .then()
-                .statusCode(200)
-                .body("size()", greaterThanOrEqualTo(3));
-    }
-
-    @Test
-    public void testTransaction() {
-        final Fruit rejected = new Fruit("Potato");
-
-        final int acceptedId = RestAssured.given()
-                .contentType(ContentType.JSON)
-                .body(JsonbBuilder.create().toJson(new Fruit("Grapes")))
-                .post("/jpa/direct/transaction")
-                .then()
-                .statusCode(200)
-                .body("id", notNullValue())
-                .body("name", is("Grapes"))
-                .extract().jsonPath().getInt("id");
-
-        try {
-            RestAssured.given()
-                    .contentType(ContentType.JSON)
-                    .body(JsonbBuilder.create().toJson(rejected))
-                    .header("rollback", true)
-                    .post("/jpa/direct/transaction")
-                    .then()
-                    .statusCode(500);
-
-            RestAssured.get("/jpa/fruit/named/Grapes")
-                    .then()
-                    .statusCode(200)
-                    .body("name", contains("Grapes"));
-
-            RestAssured.get("/jpa/fruit/named/" + rejected.getName())
-                    .then()
-                    .statusCode(200)
-                    .body("$.size()", is(0));
-        } finally {
-            RestAssured.delete("/jpa/fruit/" + acceptedId)
-                    .then()
-                    .statusCode(200);
-        }
-    }
-
-    @Test
-    public void testJpaMessageIdRepository() {
-        IntStream.of(1, 2, 1, 3, 2).forEach((id) -> {
-            RestAssured.given()
-                    .contentType(ContentType.JSON)
-                    .body(JsonbBuilder.create().toJson(new 
Fruit(Integer.toString(id))))
-                    .header("messageId", id)
-                    .post("/jpa/direct/idempotent")
-                    .then()
-                    .statusCode(200);
-        });
-
-        RestAssured.given()
-                .contentType(ContentType.JSON)
-                .post("/jpa/direct/idempotentLog")
-                .then()
-                .statusCode(200)
-                .body("$.size()", is(3))
-                .body("messageId", containsInAnyOrder("1", "2", "3"))
-                .body("processorName", hasItems("idempotentProcessor"));
-
-        RestAssured.get("/jpa/mock/idempotent")
-                .then()
-                .statusCode(200)
-                .body("size()", is(3));
-    }
-
-    public Fruit findFruit(int id) {
-        return JsonbBuilder.create().fromJson(
-                RestAssured.get("/jpa/fruit/" + id)
-                        .then()
-                        .statusCode(200)
-                        .extract().body().asString(),
-                Fruit.class);
-    }
+public class JpaTest extends JpaTestBase {
 }
diff --git 
a/integration-tests/jpa/src/test/java/org/apache/camel/quarkus/component/jpa/it/JpaTest.java
 
b/integration-tests/jpa/src/test/java/org/apache/camel/quarkus/component/jpa/it/JpaTestBase.java
similarity index 98%
copy from 
integration-tests/jpa/src/test/java/org/apache/camel/quarkus/component/jpa/it/JpaTest.java
copy to 
integration-tests/jpa/src/test/java/org/apache/camel/quarkus/component/jpa/it/JpaTestBase.java
index 5bfd83e592..873ce244ff 100644
--- 
a/integration-tests/jpa/src/test/java/org/apache/camel/quarkus/component/jpa/it/JpaTest.java
+++ 
b/integration-tests/jpa/src/test/java/org/apache/camel/quarkus/component/jpa/it/JpaTestBase.java
@@ -19,7 +19,6 @@ package org.apache.camel.quarkus.component.jpa.it;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.IntStream;
 
-import io.quarkus.test.junit.QuarkusTest;
 import io.restassured.RestAssured;
 import io.restassured.http.ContentType;
 import jakarta.json.bind.JsonbBuilder;
@@ -37,8 +36,7 @@ import static org.hamcrest.Matchers.hasItems;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.notNullValue;
 
-@QuarkusTest
-class JpaTest {
+public class JpaTestBase {
 
     static final String[] FRUITS = new String[] { "Orange", "Lemon", "Plum" };
 
diff --git 
a/extensions/jpa/runtime/src/main/java/org/apache/camel/quarkus/component/jpa/CamelJpaRecorder.java
 
b/integration-tests/jpa/src/test/java/org/apache/camel/quarkus/component/jpa/it/NamedJpaTest.java
similarity index 63%
copy from 
extensions/jpa/runtime/src/main/java/org/apache/camel/quarkus/component/jpa/CamelJpaRecorder.java
copy to 
integration-tests/jpa/src/test/java/org/apache/camel/quarkus/component/jpa/it/NamedJpaTest.java
index 658d5424ee..d793e81e4b 100644
--- 
a/extensions/jpa/runtime/src/main/java/org/apache/camel/quarkus/component/jpa/CamelJpaRecorder.java
+++ 
b/integration-tests/jpa/src/test/java/org/apache/camel/quarkus/component/jpa/it/NamedJpaTest.java
@@ -14,18 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.quarkus.component.jpa;
+package org.apache.camel.quarkus.component.jpa.it;
 
-import io.quarkus.runtime.RuntimeValue;
-import io.quarkus.runtime.annotations.Recorder;
-import org.apache.camel.component.jpa.JpaComponent;
+import io.quarkus.test.junit.QuarkusTest;
+import io.quarkus.test.junit.TestProfile;
 
-@Recorder
-public class CamelJpaRecorder {
-
-    public RuntimeValue<JpaComponent> createJpaComponent() {
-        JpaComponent component = new JpaComponent();
-        component.setTransactionStrategy(new QuarkusTransactionStrategy());
-        return new RuntimeValue<>(component);
-    }
+@QuarkusTest
+@TestProfile(NamedJpaTestProfile.class)
+public class NamedJpaTest extends JpaTestBase {
 }
diff --git 
a/extensions/jpa/runtime/src/main/java/org/apache/camel/quarkus/component/jpa/CamelJpaRecorder.java
 
b/integration-tests/jpa/src/test/java/org/apache/camel/quarkus/component/jpa/it/NamedJpaTestProfile.java
similarity index 63%
copy from 
extensions/jpa/runtime/src/main/java/org/apache/camel/quarkus/component/jpa/CamelJpaRecorder.java
copy to 
integration-tests/jpa/src/test/java/org/apache/camel/quarkus/component/jpa/it/NamedJpaTestProfile.java
index 658d5424ee..6230bec236 100644
--- 
a/extensions/jpa/runtime/src/main/java/org/apache/camel/quarkus/component/jpa/CamelJpaRecorder.java
+++ 
b/integration-tests/jpa/src/test/java/org/apache/camel/quarkus/component/jpa/it/NamedJpaTestProfile.java
@@ -14,18 +14,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.quarkus.component.jpa;
 
-import io.quarkus.runtime.RuntimeValue;
-import io.quarkus.runtime.annotations.Recorder;
-import org.apache.camel.component.jpa.JpaComponent;
+package org.apache.camel.quarkus.component.jpa.it;
 
-@Recorder
-public class CamelJpaRecorder {
+import java.util.Map;
 
-    public RuntimeValue<JpaComponent> createJpaComponent() {
-        JpaComponent component = new JpaComponent();
-        component.setTransactionStrategy(new QuarkusTransactionStrategy());
-        return new RuntimeValue<>(component);
+import io.quarkus.test.junit.QuarkusTestProfile;
+
+public class NamedJpaTestProfile implements QuarkusTestProfile {
+    @Override
+    public Map<String, String> getConfigOverrides() {
+        return Map.of("camel.component.jpa.entity-managerFactory", "#test");
     }
 }

Reply via email to