Skip to content

JAVA-6168 JAVA-6244 JAVA-6196: QE prefix/suffix/substring GA + rename Text API to String#2010

Open
nhachicha wants to merge 29 commits into
mongodb:mainfrom
nhachicha:nh/qe/prefix
Open

JAVA-6168 JAVA-6244 JAVA-6196: QE prefix/suffix/substring GA + rename Text API to String#2010
nhachicha wants to merge 29 commits into
mongodb:mainfrom
nhachicha:nh/qe/prefix

Conversation

@nhachicha

@nhachicha nhachicha commented Jul 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

Promotes Queryable Encryption string queries from preview to GA and renames the public explicit-encryption API from "Text" to "String".

  • JAVA-6168 (DRIVERS-3321) — QE prefix/suffix GA + rename TextString.
  • JAVA-6244 (DRIVERS-3540) — QE substring GA, bundled here since it's a small, closely-related follow-on now that libmongocrypt 1.20.0 is available.
  • JAVA-6196 (DRIVERS-3470) — QE Case and diacritic sensitivity not honoured for explicit encryption.

Changes

Public API (driver-core, com.mongodb.client.model.vault) — additive / backward compatible:

  • New StringOptions mirroring TextOptions. The QE String feature is GA, so StringOptions and EncryptOptions.stringOptions()/getStringOptions() are stable (no @Alpha). TextOptions/textOptions()/getTextOptions() are retained as @Deprecated (kept @Alpha, so the deprecated path can be removed without a major bump).
  • EncryptOptions: add stringOptions(...)/getStringOptions(); deprecate textOptions(...)/getTextOptions() (independent backing fields; stringOptions wins, falls back to textOptions).
  • Docs: algorithm "TextPreview""String"; queryType documents prefix/suffix/substring (GA, server 9.0+) plus the deprecated prefixPreview/suffixPreview/substringPreview aliases (pre-9.0). New API is @since 5.9.

libmongocrypt: 1.18.11.20.0 (stable prefix/suffix in 1.19.0, stable substring in 1.20.0). No JNA binding changes.

Tests:

  • Rewrote the QE string explicit-encryption prose test to spec test 27 (cases 1–11): algorithm "String" + stringOptions, GA (prefix/suffix/substring, server 9.0+) vs preview (*Preview, pre-9.0) paths, gated on server version.
  • Un-skipped the QE-Text-substring GA unified spec test (now supported on libmongocrypt 1.20.0).
  • Spec submodule updated (via merge of main).

Compatibility

No breaking changes — all additions or retained deprecations; no major version bump required. Note: passing "TextPreview" as the algorithm value now errors at libmongocrypt (removed in 1.19.x); users must use "String".

nhachicha added 18 commits June 29, 2026 11:07
Provides GA support for QE 'prefix'/'suffix' query types and the 'string'
algorithm (formerly 'textPreview'), and restores 'prefixPreview'/'suffixPreview'
for pre-9.0 servers. Required by the Text->String API rename.
Updates testing/resources/specifications 4484038..8990543, bringing the GA
QE-Text unified tests and String Explicit Encryption prose test (DRIVERS-3321,
DRIVERS-3470).
libmongocrypt 1.20.0 adds stable support for substring queries (the GA
'substring' query type), unblocking DRIVERS-3540/JAVA-6244.
…se GA/preview split)

- Un-skip the QE-Text-substring GA unified spec test (now supported via libmongocrypt 1.20.0).
- Prose test 27: split substring cases 5/6 into GA (substring, server 9.0+/libmongocrypt 1.20+)
  and preview (substringPreview, server pre-9.0) paths using the new substring-preview collection;
  update seed strMaxQueryLength to 6; gate cases 10/11 to pre-9.0 per the updated spec.
@nhachicha nhachicha requested a review from a team as a code owner July 4, 2026 16:26
@nhachicha nhachicha requested review from apmasell and Copilot and removed request for apmasell July 4, 2026 16:26
@nhachicha nhachicha changed the title feat(JAVA-6168): QE prefix/suffix/substring GA + rename Text API to String JAVA-6168: QE prefix/suffix/substring GA + rename Text API to String Jul 4, 2026
@nhachicha nhachicha marked this pull request as draft July 4, 2026 16:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Promotes Queryable Encryption explicit-encryption string queries from the preview “Text” API to the GA “String” API surface, adds StringOptions, and bumps bundled libmongocrypt to 1.20.0 to enable GA prefix/suffix/substring behavior across server versions.

Changes:

  • Introduces StringOptions and EncryptOptions.stringOptions(...), while deprecating TextOptions / EncryptOptions.textOptions(...) and mapping new options through the existing libmongocrypt “text options” document.
  • Updates functional and unit tests to exercise GA (prefix/suffix/substring) vs pre-9.0 preview (*Preview) queryType behavior.
  • Updates mongodb-crypt packaging to download libmongocrypt 1.20.0 and adjusts GPG verification homedir handling to avoid macOS socket path limits.

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
mongodb-crypt/src/main/com/mongodb/internal/crypt/capi/MongoExplicitEncryptOptions.java Updates internal Javadoc to reflect the algorithm name change to "String".
mongodb-crypt/build.gradle.kts Bumps bundled libmongocrypt to 1.20.0 and moves GPG homedir to system temp to avoid macOS path-length failures.
driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTestModifications.java Removes skip for the substring unified test now that it’s supported.
driver-sync/src/test/functional/com/mongodb/client/AbstractClientEncryptionTextExplicitEncryptionTest.java Reworks QE prose-style functional tests to cover GA vs preview query types and adds additional cases.
driver-core/src/test/unit/com/mongodb/internal/client/vault/EncryptOptionsHelperTest.java Adds unit tests for mapping StringOptions (and deprecated fallback) into the libmongocrypt options document.
driver-core/src/test/unit/com/mongodb/client/model/vault/StringOptionsTest.java Adds unit tests for the new StringOptions value object.
driver-core/src/test/unit/com/mongodb/client/model/vault/EncryptOptionsTest.java Adds unit tests for EncryptOptions storing stringOptions and deprecated textOptions.
driver-core/src/main/com/mongodb/internal/client/vault/EncryptOptionsHelper.java Implements StringOptions → libmongocrypt “text options” document mapping with deprecated fallback.
driver-core/src/main/com/mongodb/client/model/vault/TextOptions.java Deprecates TextOptions and adjusts defaults for boolean flags.
driver-core/src/main/com/mongodb/client/model/vault/StringOptions.java Adds the new StringOptions API and associated documentation.
driver-core/src/main/com/mongodb/client/model/vault/EncryptOptions.java Adds stringOptions accessors, deprecates textOptions, and updates Javadocs/toString accordingly.
.gitignore Ignores docs/superpowers/.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread driver-core/src/main/com/mongodb/client/model/vault/EncryptOptions.java Outdated
Comment thread driver-core/src/main/com/mongodb/client/model/vault/EncryptOptions.java Outdated
Comment thread driver-core/src/main/com/mongodb/client/model/vault/StringOptions.java Outdated
Comment thread driver-core/src/main/com/mongodb/client/model/vault/StringOptions.java Outdated
skipVerify.set(skipCryptVerify)
expectedFingerprint.set("F2F5BF4ABF517E039AFCADAA81F1404DEBACA586")
gnupgHome.set(layout.buildDirectory.dir("jnaLibs/gnupg"))
// Keep the scratch GPG keyring under the system temp dir, not the module build dir. gpg derives

@nhachicha nhachicha Jul 4, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to the reviewer: This fix an issue where gpg invocation used to fail locally when invoked from Gradle/IDE under a deeply nested directories. Worth checking under Windows as well cc @strogiyotec

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch

…ses 10/11, precedence test

- Update EncryptOptions/StringOptions Javadocs: substring is GA (queryType 'substring', server 9.0+),
  'substringPreview' is the deprecated pre-9.0 alias (was still documented as experimental/preview).
- Prose test cases 10/11 (auto-encrypted substring ci-di): run on server 9.0+ (assumeTrue(gaSupported)),
  matching the substring-ci-di 9.0+ setup requirement and the prefix/suffix ci-di cases 8/9. The spec's
  'skip on 9.0.0+' contradicts its own setup; TODO-JAVA-6244 pending upstream clarification.
- Add EncryptOptionsHelper precedence test: stringOptions wins when both stringOptions and textOptions set.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 15 changed files in this pull request and generated 2 comments.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 15 changed files in this pull request and generated 2 comments.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 15 changed files in this pull request and generated 3 comments.

…n comment

- EncryptOptions.getQueryType() javadoc referenced only equality/range; point it to
  queryType(String) so it stays consistent with the supported-types list.
- MongoExplicitEncryptOptions.textOptions @param: clarify it takes the string options as a BSON document.
- Prose test: reword the libmongocrypt version comment to reflect the class-level 1.19.1 floor.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 15 changed files in this pull request and generated 2 comments.

Comment thread mongodb-crypt/build.gradle.kts
…ion-agnostic

The example hard-coded 1.18.1, now stale after the 1.20.0 bump; use a <version> placeholder.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 15 changed files in this pull request and generated 2 comments.

Comment thread mongodb-crypt/build.gradle.kts
Comment thread mongodb-crypt/build.gradle.kts
The VerifyLibmongocryptTask KDoc still said the keyring lives under build/ and that clean resets
trust; the homedir now lives under the system temp dir and verify() recreates it each run. Correct
the comment to match.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 15 changed files in this pull request and generated no new comments.

QE prefix/suffix/substring string queries are GA (libmongocrypt "Stable support" in 1.19/1.20,
server 9.0), so the @Alpha(Reason.SERVER) marking no longer applies. Remove @Alpha from the
StringOptions class and EncryptOptions.stringOptions()/getStringOptions(). The deprecated
TextOptions path keeps @Alpha (removable without a major bump). @mongodb.server.release stays 8.2
(the feature is usable from 8.2 via the preview query types; GA query types need 9.0).
* @mongodb.server.release 8.2
* @mongodb.driver.manual /core/queryable-encryption/ queryable encryption
*/
public class StringOptions {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to reviewer: Class similar to TextOptions

nhachicha added 2 commits July 6, 2026 14:43
The driver bundles a fixed libmongocrypt (1.20.0), so getMongoCryptVersion() is constant in CI and
the substring-GA libmongocrypt gate was always satisfied (substringGaSupported == gaSupported). Drop
SUBSTRING_GA_LIB_MONGOCRYPT_VERSION/substringGaSupported and gate substring collection creation, seed,
and cases 5/6/10/11 on gaSupported (server version, which does vary across CI). Also trims two
over-verbose doc comments.
@nhachicha nhachicha changed the title JAVA-6168: QE prefix/suffix/substring GA + rename Text API to String JAVA-6168 JAVA-6244: QE prefix/suffix/substring GA + rename Text API to String Jul 6, 2026
@nhachicha nhachicha requested a review from rozza July 6, 2026 14:52
@nhachicha nhachicha marked this pull request as ready for review July 6, 2026 14:52
@nhachicha nhachicha changed the title JAVA-6168 JAVA-6244: QE prefix/suffix/substring GA + rename Text API to String JAVA-6168 JAVA-6244 JAVA-6196: QE prefix/suffix/substring GA + rename Text API to String Jul 6, 2026

@rozza rozza left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good - only minor nits

* @mongodb.server.release 8.2
* @mongodb.driver.manual /core/queryable-encryption/ queryable encryption
*/
public class StringOptions {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets add toString method - not sure why TextOptions didnt have one but it may be helpful for users if they need to debug.

skipVerify.set(skipCryptVerify)
expectedFingerprint.set("F2F5BF4ABF517E039AFCADAA81F1404DEBACA586")
gnupgHome.set(layout.buildDirectory.dir("jnaLibs/gnupg"))
// Keep the scratch GPG keyring under the system temp dir, not the module build dir. gpg derives

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch


public abstract class AbstractClientEncryptionStringExplicitEncryptionTest {

private static final ServerVersion REQUIRED_LIB_MONGOCRYPT_VERSION = new ServerVersion(asList(1, 19, 1));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not 100% this is needed, unless we test against different versions and then the user would have to explicitly use a lower version than packaged.

Recommend naming MIN_SUPPORTED_LIB_MONGOCRYPT_VERSION as it reflects the usage better.

// limit, so on a fresh keyring gpg fails ("can't connect to the gpg-agent: File name too long")
// and exits non-zero even though the import/verify would otherwise succeed. A short,
// checkout-independent homedir avoids this; the hash suffix isolates builds of different
// checkouts. verify() recreates this directory on every run, so a stable name is safe.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it overwrite it? previously ./gradlew clean cleaned up the build dir. I'm not sure it actually matters anyway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants