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 3fe7181f11..188a4bb70d 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 @@ -157,6 +157,10 @@ public class MongoDocumentStore implements DocumentStore { */ public static final long DEFAULT_THROTTLING_TIME_MS = Long.getLong("oak.mongo.throttlingTime", 20); + /** + * Document size of 16MB is a limit in Mongo + */ + public static final long SIZE_LIMIT = 16793600; /** * nodeNameLimit for node name based on Mongo Version */ @@ -1074,6 +1078,10 @@ public class MongoDocumentStore implements DocumentStore { } } + int size = updateOp.toString().length(); + if(size > SIZE_LIMIT) { + LOG.warn("Document with ID={} has size={} that exceeds 16MB size limit", updateOp.getId(), size); + } // conditional update failed or not possible // perform operation and get complete document Bson query = createQueryForUpdate(updateOp.getId(), updateOp.getConditions()); @@ -1350,6 +1358,10 @@ public class MongoDocumentStore implements DocumentStore { int i = 0; for (UpdateOp updateOp : updateOps) { String id = updateOp.getId(); + int size = updateOp.toString().length(); + if(size > SIZE_LIMIT) { + LOG.warn("Document with ID={} has size={} that exceeds 16MB size limit", id, size); + } Bson query = createQueryForUpdate(id, updateOp.getConditions()); // fail on insert when isNew == false boolean failInsert = !updateOp.isNew(); @@ -1366,6 +1378,7 @@ public class MongoDocumentStore implements DocumentStore { bulkIds[i++] = id; } + BulkWriteResult bulkResult; Set failedUpdates = new HashSet(); Set upserts = new HashSet(); @@ -1410,6 +1423,10 @@ public class MongoDocumentStore implements DocumentStore { BasicDBObject doc = new BasicDBObject(); inserts.add(doc); doc.put(Document.ID, update.getId()); + int size = update.toString().length(); + if(size > SIZE_LIMIT) { + LOG.warn("Document with ID={} has size={} that exceeds 16MB size limit", update.getId(), size); + } UpdateUtils.assertUnconditional(update); T target = collection.newDocument(this); UpdateUtils.applyChanges(target, update); @@ -1872,6 +1889,10 @@ public class MongoDocumentStore implements DocumentStore { BasicDBObject incUpdates = new BasicDBObject(); BasicDBObject unsetUpdates = new BasicDBObject(); + int size = updateOp.toString().length(); + if(size > SIZE_LIMIT) { + LOG.warn("Document with ID={} has size={} that exceeds 16MB size limit", updateOp.getId(), size); + } // always increment modCount updateOp.increment(Document.MOD_COUNT, 1); diff --git a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDBExceptionTest.java b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDBExceptionTest.java index 73a1d9d49d..b6aec5ac55 100644 --- a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDBExceptionTest.java +++ b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDBExceptionTest.java @@ -30,6 +30,9 @@ import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.Ignore; + +import java.util.Arrays; import static java.util.Collections.singletonList; import static org.hamcrest.Matchers.containsString; @@ -132,6 +135,31 @@ public class MongoDBExceptionTest { } } + @Test + @Ignore + public void add16MBDoc() throws Exception { + //DocumentStore docStore = openDocumentStore(); + + UpdateOp updateOp = new UpdateOp("/", false); + + // create a 1 MB property + char[] chars = new char[1024 * 1024]; + + Arrays.fill(chars, '0'); + String content = new String(chars); + + //create more than 16MB properties + for (int i = 0; i < 17; i++) { + updateOp.set("property"+ Integer.toString(i), content); + } + + int size = updateOp.toString().length(); + + store.createOrUpdate(Collection.NODES, updateOp); + NodeDocument doc = store.find(Collection.NODES, "/"); + // assertNotNull(doc); + } + private void setExceptionMsg() { client.setExceptionBeforeUpdate(exceptionMsg); client.setExceptionBeforeQuery(exceptionMsg);