This is an automated email from the ASF dual-hosted git repository. reschke pushed a commit to branch OAK-10650 in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git
commit 870cc5550110c2267826af3d9e361fadc3eb605e Author: Julian Reschke <[email protected]> AuthorDate: Wed Feb 14 13:55:00 2024 +0100 OAK-10650: MongoDocumentStore.findDocuments can fail with BSON exception --- .../plugins/document/mongo/MongoDocumentStore.java | 52 +++++++++++++++++++--- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java index 1f156f4100..604829b38d 100644 --- a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java +++ b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java @@ -84,6 +84,7 @@ import org.apache.jackrabbit.oak.plugins.document.locks.StripedNodeDocumentLocks import org.apache.jackrabbit.oak.plugins.document.util.Utils; import org.apache.jackrabbit.oak.stats.Clock; import org.apache.jackrabbit.oak.commons.PerfLogger; +import org.bson.BSONException; import org.bson.BsonMaximumSizeExceededException; import org.bson.conversions.Bson; import org.jetbrains.annotations.NotNull; @@ -1524,12 +1525,48 @@ public class MongoDocumentStore implements DocumentStore { } private <T extends Document> Map<String, T> findDocuments(Collection<T> collection, Set<String> keys) { - Map<String, T> docs = new HashMap<String, T>(); - if (!keys.isEmpty()) { - List<Bson> conditions = new ArrayList<>(keys.size()); - for (String key : keys) { - conditions.add(getByKeyQuery(key)); + try { + Map<String, T> docs = new HashMap<String, T>(); + if (!keys.isEmpty()) { + List<Bson> conditions = new ArrayList<>(keys.size()); + for (String key : keys) { + conditions.add(getByKeyQuery(key)); + } + MongoCollection<BasicDBObject> dbCollection; + if (secondariesWithinAcceptableLag()) { + dbCollection = getDBCollection(collection); + } else { + lagTooHigh(); + dbCollection = getDBCollection(collection).withReadPreference(ReadPreference.primary()); + } + execute(session -> { + FindIterable<BasicDBObject> cursor; + if (session != null) { + cursor = dbCollection.find(session, Filters.or(conditions)); + } else { + cursor = dbCollection.find(Filters.or(conditions)); + } + for (BasicDBObject doc : cursor) { + T foundDoc = convertFromDBObject(collection, doc); + docs.put(foundDoc.getId(), foundDoc); + } + return null; + }, collection); } + return docs; + } catch (BSONException ex) { + // TODO: refactor, see OAK-10650 + LOG.error("trying bulk find, retrying one-by-one", ex); + return findDocumentsOneByOne(collection, keys); + } + } + + // variant of findDocuments that avoids BSON exception by iterating instead of doing a bulk operation + private <T extends Document> Map<String, T> findDocumentsOneByOne(Collection<T> collection, Set<String> keys) { + Map<String, T> docs = new HashMap<String, T>(); + for (String key : keys) { + Bson condition = getByKeyQuery(key); + MongoCollection<BasicDBObject> dbCollection; if (secondariesWithinAcceptableLag()) { dbCollection = getDBCollection(collection); @@ -1540,9 +1577,9 @@ public class MongoDocumentStore implements DocumentStore { execute(session -> { FindIterable<BasicDBObject> cursor; if (session != null) { - cursor = dbCollection.find(session, Filters.or(conditions)); + cursor = dbCollection.find(session, condition); } else { - cursor = dbCollection.find(Filters.or(conditions)); + cursor = dbCollection.find(condition); } for (BasicDBObject doc : cursor) { T foundDoc = convertFromDBObject(collection, doc); @@ -1551,6 +1588,7 @@ public class MongoDocumentStore implements DocumentStore { return null; }, collection); } + return docs; }
