From bb402b24ce862def36347f9e0490bb21afe0a6da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mathieu?= Date: Mon, 2 Jan 2023 12:01:39 +0100 Subject: [PATCH] MongoDB with Panache: allow setting per collection read preference Fixes #29997 --- .../mongodb/runtime/MongoClientConfig.java | 2 +- .../mongodb/panache/common/MongoEntity.java | 6 ++++++ .../runtime/ReactiveMongoOperations.java | 17 +++++++++++++++-- .../panache/common/runtime/MongoOperations.java | 17 +++++++++++++++-- .../it/mongodb/panache/book/BookEntity.kt | 2 +- .../panache/reactive/book/ReactiveBookEntity.kt | 2 +- .../it/mongodb/panache/book/BookEntity.java | 2 +- .../reactive/book/ReactiveBookEntity.java | 2 +- 8 files changed, 41 insertions(+), 9 deletions(-) diff --git a/extensions/mongodb-client/runtime/src/main/java/io/quarkus/mongodb/runtime/MongoClientConfig.java b/extensions/mongodb-client/runtime/src/main/java/io/quarkus/mongodb/runtime/MongoClientConfig.java index acc9c7761fa68..8c631bff5bb38 100644 --- a/extensions/mongodb-client/runtime/src/main/java/io/quarkus/mongodb/runtime/MongoClientConfig.java +++ b/extensions/mongodb-client/runtime/src/main/java/io/quarkus/mongodb/runtime/MongoClientConfig.java @@ -179,7 +179,7 @@ public class MongoClientConfig { public Optional readConcern; /** - * Configures the read preferences. + * Configures the read preference. * Supported values are: {@code primary|primaryPreferred|secondary|secondaryPreferred|nearest} */ @ConfigItem diff --git a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/common/MongoEntity.java b/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/common/MongoEntity.java index 59902dcc0e69e..7fbc6ff55c917 100644 --- a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/common/MongoEntity.java +++ b/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/common/MongoEntity.java @@ -26,4 +26,10 @@ * The name of the MongoDB client (if not set the default client will be used). */ String clientName() default ""; + + /** + * Configures the read preference for the collection of this entity. + * Supported values are: {@code primary|primaryPreferred|secondary|secondaryPreferred|nearest} + */ + String readPreference() default ""; } diff --git a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/common/reactive/runtime/ReactiveMongoOperations.java b/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/common/reactive/runtime/ReactiveMongoOperations.java index 2ba4c3a035b3f..c359c8ed4f775 100644 --- a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/common/reactive/runtime/ReactiveMongoOperations.java +++ b/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/common/reactive/runtime/ReactiveMongoOperations.java @@ -22,6 +22,7 @@ import org.bson.codecs.EncoderContext; import org.jboss.logging.Logger; +import com.mongodb.ReadPreference; import com.mongodb.client.model.InsertOneModel; import com.mongodb.client.model.ReplaceOneModel; import com.mongodb.client.model.ReplaceOptions; @@ -216,8 +217,20 @@ public Uni delete(Object entity) { public ReactiveMongoCollection mongoCollection(Class entityClass) { MongoEntity mongoEntity = entityClass.getAnnotation(MongoEntity.class); ReactiveMongoDatabase database = mongoDatabase(mongoEntity); - if (mongoEntity != null && !mongoEntity.collection().isEmpty()) { - return database.getCollection(mongoEntity.collection(), entityClass); + if (mongoEntity != null) { + ReactiveMongoCollection collection = mongoEntity.collection().isEmpty() + ? database.getCollection(entityClass.getSimpleName(), entityClass) + : database.getCollection(mongoEntity.collection(), entityClass); + if (!mongoEntity.readPreference().isEmpty()) { + try { + collection = collection.withReadPreference(ReadPreference.valueOf(mongoEntity.readPreference())); + } catch (IllegalArgumentException iae) { + throw new IllegalArgumentException("Illegal read preference " + mongoEntity.readPreference() + + " configured in the @MongoEntity annotation of " + entityClass.getName() + "." + + " Supported values are primary|primaryPreferred|secondary|secondaryPreferred|nearest"); + } + } + return collection; } return database.getCollection(entityClass.getSimpleName(), entityClass); } diff --git a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/common/runtime/MongoOperations.java b/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/common/runtime/MongoOperations.java index 27ef1a5c68452..72640961572e7 100644 --- a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/common/runtime/MongoOperations.java +++ b/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/common/runtime/MongoOperations.java @@ -24,6 +24,7 @@ import org.bson.codecs.EncoderContext; import org.jboss.logging.Logger; +import com.mongodb.ReadPreference; import com.mongodb.client.ClientSession; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoCollection; @@ -190,8 +191,20 @@ public void delete(Object entity) { public MongoCollection mongoCollection(Class entityClass) { MongoEntity mongoEntity = entityClass.getAnnotation(MongoEntity.class); MongoDatabase database = mongoDatabase(mongoEntity); - if (mongoEntity != null && !mongoEntity.collection().isEmpty()) { - return database.getCollection(mongoEntity.collection(), entityClass); + if (mongoEntity != null) { + MongoCollection collection = mongoEntity.collection().isEmpty() + ? database.getCollection(entityClass.getSimpleName(), entityClass) + : database.getCollection(mongoEntity.collection(), entityClass); + if (!mongoEntity.readPreference().isEmpty()) { + try { + collection = collection.withReadPreference(ReadPreference.valueOf(mongoEntity.readPreference())); + } catch (IllegalArgumentException iae) { + throw new IllegalArgumentException("Illegal read preference " + mongoEntity.readPreference() + + " configured in the @MongoEntity annotation of " + entityClass.getName() + "." + + " Supported values are primary|primaryPreferred|secondary|secondaryPreferred|nearest"); + } + } + return collection; } return database.getCollection(entityClass.getSimpleName(), entityClass); } diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookEntity.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookEntity.kt index 2ea85aaf953ab..2956c57ed2385 100644 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookEntity.kt +++ b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookEntity.kt @@ -11,7 +11,7 @@ import org.bson.codecs.pojo.annotations.BsonProperty import org.bson.types.ObjectId import java.time.LocalDate -@MongoEntity(collection = "TheBookEntity", clientName = "cl2") +@MongoEntity(collection = "TheBookEntity", clientName = "cl2", readPreference = "primary") class BookEntity : PanacheMongoEntity() { companion object : PanacheMongoCompanion { override fun findById(id: ObjectId): BookEntity { diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/book/ReactiveBookEntity.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/book/ReactiveBookEntity.kt index 7ed1c17287348..728875fe20dfd 100644 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/book/ReactiveBookEntity.kt +++ b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/book/ReactiveBookEntity.kt @@ -11,7 +11,7 @@ import org.bson.codecs.pojo.annotations.BsonProperty import java.time.LocalDate import java.util.ArrayList -@MongoEntity(collection = "TheBookEntity", clientName = "cl2") +@MongoEntity(collection = "TheBookEntity", clientName = "cl2", readPreference = "primary") class ReactiveBookEntity : ReactivePanacheMongoEntity() { companion object : ReactivePanacheMongoCompanion diff --git a/integration-tests/mongodb-panache/src/main/java/io/quarkus/it/mongodb/panache/book/BookEntity.java b/integration-tests/mongodb-panache/src/main/java/io/quarkus/it/mongodb/panache/book/BookEntity.java index 6da808cd876f4..a6ff655ef97b7 100644 --- a/integration-tests/mongodb-panache/src/main/java/io/quarkus/it/mongodb/panache/book/BookEntity.java +++ b/integration-tests/mongodb-panache/src/main/java/io/quarkus/it/mongodb/panache/book/BookEntity.java @@ -13,7 +13,7 @@ import io.quarkus.mongodb.panache.PanacheMongoEntity; import io.quarkus.mongodb.panache.common.MongoEntity; -@MongoEntity(collection = "TheBookEntity", clientName = "cl2") +@MongoEntity(collection = "TheBookEntity", clientName = "cl2", readPreference = "primary") public class BookEntity extends PanacheMongoEntity { @BsonProperty("bookTitle") private String title; diff --git a/integration-tests/mongodb-panache/src/main/java/io/quarkus/it/mongodb/panache/reactive/book/ReactiveBookEntity.java b/integration-tests/mongodb-panache/src/main/java/io/quarkus/it/mongodb/panache/reactive/book/ReactiveBookEntity.java index 2a7437d1db7e3..2c844dbcc9550 100644 --- a/integration-tests/mongodb-panache/src/main/java/io/quarkus/it/mongodb/panache/reactive/book/ReactiveBookEntity.java +++ b/integration-tests/mongodb-panache/src/main/java/io/quarkus/it/mongodb/panache/reactive/book/ReactiveBookEntity.java @@ -14,7 +14,7 @@ import io.quarkus.mongodb.panache.common.MongoEntity; import io.quarkus.mongodb.panache.reactive.ReactivePanacheMongoEntity; -@MongoEntity(collection = "TheBookEntity", clientName = "cl2") +@MongoEntity(collection = "TheBookEntity", clientName = "cl2", readPreference = "primary") public class ReactiveBookEntity extends ReactivePanacheMongoEntity { @BsonProperty("bookTitle") private String title;