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 eb3d702e98 Fix #7254 to support named entityManagerFactory in
camel-quarkus-jpa
eb3d702e98 is described below
commit eb3d702e989d159b8315ac8f1494c368b7a9f902
Author: Zheng Feng <[email protected]>
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");
}
}