build(#29): adopt qbit-quick-search 1.0.0-RC.2 #30

Open
KofTwentyTwo wants to merge 2 commits from feature/GH-29-adopt-quick-search-rc2 into develop
pull from: feature/GH-29-adopt-quick-search-rc2
KofTwentyTwo commented 2026-10-08 12:25:26 +00:00 (Migrated from github.com)

Pull Request

Description

What does this PR do?
Adopts com.kingsrook.qbits:qbit-quick-search:1.0.0-RC.2 (Maven Central, built against qqq 4.1.0-RC.1) so its RC feedback can go back to QRun-IO/qbit-quick-search#12.

  • qqq-all-bom: qbit-quick-search.version is now 1.0.0-RC.2 (was 0.2.1-SNAPSHOT). The comment says quick search now has a release candidate on qbit-build-parent 2.0.0.

  • DemoQBits.addFull: uses the 1.0 API.

    • The manual instance.addQBit(...) is gone because the producer registers com.kingsrook.qbits:quick-search itself.
    • The connection goes through opensearchUrl, built with java.net.URI from the existing QQQ_ALL_OPENSEARCH_HOST/PORT/SSL settings, so the env contract is unchanged and IPv6 hosts work.
    • withSchedulerName("demoScheduler") schedules the basepull.
    • Credentials are passed as ${env.QQQ_ALL_OPENSEARCH_USER} and ${env.QQQ_ALL_OPENSEARCH_PASSWORD} references, and only when they are set.
    • The startup mode comes from a new optional, case-insensitive QQQ_ALL_OPENSEARCH_STARTUP_MODE. It defaults to FAIL_FAST; the full-profile tests set DEGRADED.
  • infra/postgres/06-quick-search-permissions.sql: gives the admin role quickSearchAdmin.hasAccess and read/write on quickSearchIndex, quickSearchIndexRun and quickSearchFailedEvent. 1.0 protects the admin app, the processes and those tables. Without this grant the full smoke's quickSearchFullReindex call would be denied.

  • Tests: FullQBitsTest covers the 1.0 behavior:

    • the QBit registers itself exactly once
    • opensearchUrl, DEGRADED and demoScheduler are set, and the basepull schedule uses demoScheduler
    • the record-change listener and the quickSearchFailedEvent table are registered
    • credentials stay ${env.X} references
    • an IPv6 host gets brackets in the URL
    • startup fails fast without OpenSearch unless the mode is DEGRADED, and the error message is checked
    • the startup mode is case-insensitive, and an invalid mode is rejected with the bad value in the message
    • the admin grant names are read from 06-quick-search-permissions.sql and are enforced, so the test and the SQL cannot drift

    StackBomTest pins 1.0.0-RC.2.

  • qqq-all-app/README.md: documents the new variable, the credential and TLS rule, the permissions, and the upgrade path for volumes created with 0.x. It also says the demo customer table has no modifyDate, so incremental basepull is off for it. After the first basepull, the index stays current through real-time indexing, failed-event replay, and on-demand reconcile or full reindex. No reconcile cron is configured.

Breaking changes (full profile):

  • Startup now fails when OpenSearch is unreachable, because FAIL_FAST is the 1.0 default. Set QQQ_ALL_OPENSEARCH_STARTUP_MODE=DEGRADED to boot without OpenSearch.
  • OpenSearch credentials over plain HTTP are refused. Setting QQQ_ALL_OPENSEARCH_USER/PASSWORD now requires QQQ_ALL_OPENSEARCH_SSL=true.
  • Volumes created with quick-search 0.x do not start. They need the new grant file, new quick_search_* tables (the startup column check rejects the 0.x ones), and one quickSearchFullReindex for mapping v2. The app README gives the steps.

Related Issue:
Closes #29

Type of Change

  • Bug Fix - Fixes an existing issue
  • New Feature - Adds new functionality
  • Breaking Change - Fix or feature that would cause existing functionality to not work as expected
  • Documentation Update - Updates documentation
  • Refactoring - Code change that neither fixes a bug nor adds a feature
  • Build / CI - Changes to the Maven build, CircleCI, compose, or image
  • Test Addition - Adding missing tests or correcting existing tests

Testing

How has this been tested?

  • Unit Tests: All unit tests pass
  • Integration Tests: Integration tests pass
  • Profiles: Checked the affected profile(s) (core, full)
  • Manual Testing: Tested manually in a development environment

Test Commands:

mvn -B -ntp verify
# BUILD SUCCESS: StackBomTest 2/2; app unit tests 28 run, 0 failures, 2 skipped
# (PostgresCompatibilityTest and FullProfileBrokerIntegrationTest are opt-in, as before);
# failsafe 7/7 (CoreJarIT, PackagedNoticesIT)
python3 -m unittest discover -s scripts -p 'test_*.py'   # 45 tests OK
python3 scripts/run_full_smoke.py                       # see below

Local full Compose smoke (OpenSearch 2.19.1):

  • The stack became healthy with FAIL_FAST. Quick search created qqq-all-customers-v2-<epoch> behind the qqq-all-customers alias and started its runtime service. The scheduled basepull on demoScheduler indexed both seeded customers with 0 errors.
  • The smoke then stopped at the OIDC login, before its quick-search step. QQQ's OAuth2AuthenticationModule threw ClassCastException: Tokens cannot be cast to OIDCTokens. Unchanged develop (e35f1f6) fails the same way, both locally and in CI (https://github.com/QRun-IO/qqq-all/actions/runs/37777430884), so this failure is not caused by this change.

Checklist

Before submitting this PR, please ensure:

  • Code Style: Follows QQQ's Code Review Standards
  • Tests: All tests pass
  • Documentation: Updated the README or docs where behavior changed
  • Secrets: No secrets committed; any demo credentials are marked demo-only and overridable by env
  • Breaking Changes: Documented any breaking changes
  • Commit Messages: Follow conventional commit format
  • Self Review: Code has been reviewed by the author

Additional Information

Adoption notes

  • RC.2 resolves cleanly against this stack's qqq 4.1.0-SNAPSHOT. The BOM's qqq pin wins over the 4.1.0-RC.1 import in quick-search's default-active qqq-snapshot profile. opensearch-java 3.10.0, httpclient5 5.6.3 and httpcore5 5.4.3 line up.
  • The 0.x fluent API still compiles against RC.2, as the migration guide says. Leaving the old addQBit in place throws IllegalArgumentException: Attempted to add a second qBit ... com.kingsrook.qbits:quick-search, as the guide warns.
  • With the 1.0 default FAIL_FAST, the existing full-profile tests (OpenSearch on port 1) fail inside defineQInstance(). The error says to set startupMode=DEGRADED, which is clear and actionable.
  • For a table configured with withSearchableTable and no modifyDate, quick-search turns off incremental basepull without logging anything. Annotated tables log a warning in the same case.
  • Release gate: RC.2 builds on qbit-build-parent 2.0.0 (qqq 4.0.0 BOM) and gets 4.1.0-RC.1 through a profile. docs/release.md requires qbits built on a parent that imports the released QQQ version, so a quick-search build on qbit-build-parent 2.1.0 is still needed before qqq-all's release.
# Pull Request ## Description **What does this PR do?** Adopts `com.kingsrook.qbits:qbit-quick-search:1.0.0-RC.2` (Maven Central, built against qqq 4.1.0-RC.1) so its RC feedback can go back to QRun-IO/qbit-quick-search#12. - `qqq-all-bom`: `qbit-quick-search.version` is now `1.0.0-RC.2` (was `0.2.1-SNAPSHOT`). The comment says quick search now has a release candidate on qbit-build-parent 2.0.0. - `DemoQBits.addFull`: uses the 1.0 API. - The manual `instance.addQBit(...)` is gone because the producer registers `com.kingsrook.qbits:quick-search` itself. - The connection goes through `opensearchUrl`, built with `java.net.URI` from the existing `QQQ_ALL_OPENSEARCH_HOST`/`PORT`/`SSL` settings, so the env contract is unchanged and IPv6 hosts work. - `withSchedulerName("demoScheduler")` schedules the basepull. - Credentials are passed as `${env.QQQ_ALL_OPENSEARCH_USER}` and `${env.QQQ_ALL_OPENSEARCH_PASSWORD}` references, and only when they are set. - The startup mode comes from a new optional, case-insensitive `QQQ_ALL_OPENSEARCH_STARTUP_MODE`. It defaults to `FAIL_FAST`; the full-profile tests set `DEGRADED`. - `infra/postgres/06-quick-search-permissions.sql`: gives the admin role `quickSearchAdmin.hasAccess` and read/write on `quickSearchIndex`, `quickSearchIndexRun` and `quickSearchFailedEvent`. 1.0 protects the admin app, the processes and those tables. Without this grant the full smoke's `quickSearchFullReindex` call would be denied. - Tests: `FullQBitsTest` covers the 1.0 behavior: - the QBit registers itself exactly once - `opensearchUrl`, `DEGRADED` and `demoScheduler` are set, and the basepull schedule uses `demoScheduler` - the record-change listener and the `quickSearchFailedEvent` table are registered - credentials stay `${env.X}` references - an IPv6 host gets brackets in the URL - startup fails fast without OpenSearch unless the mode is `DEGRADED`, and the error message is checked - the startup mode is case-insensitive, and an invalid mode is rejected with the bad value in the message - the admin grant names are read from `06-quick-search-permissions.sql` and are enforced, so the test and the SQL cannot drift `StackBomTest` pins `1.0.0-RC.2`. - `qqq-all-app/README.md`: documents the new variable, the credential and TLS rule, the permissions, and the upgrade path for volumes created with 0.x. It also says the demo `customer` table has no `modifyDate`, so incremental basepull is off for it. After the first basepull, the index stays current through real-time indexing, failed-event replay, and on-demand reconcile or full reindex. No reconcile cron is configured. **Breaking changes (full profile):** - Startup now fails when OpenSearch is unreachable, because `FAIL_FAST` is the 1.0 default. Set `QQQ_ALL_OPENSEARCH_STARTUP_MODE=DEGRADED` to boot without OpenSearch. - OpenSearch credentials over plain HTTP are refused. Setting `QQQ_ALL_OPENSEARCH_USER`/`PASSWORD` now requires `QQQ_ALL_OPENSEARCH_SSL=true`. - Volumes created with quick-search 0.x do not start. They need the new grant file, new `quick_search_*` tables (the startup column check rejects the 0.x ones), and one `quickSearchFullReindex` for mapping v2. The app README gives the steps. **Related Issue:** Closes #29 ## Type of Change - [ ] **Bug Fix** - Fixes an existing issue - [ ] **New Feature** - Adds new functionality - [x] **Breaking Change** - Fix or feature that would cause existing functionality to not work as expected - [x] **Documentation Update** - Updates documentation - [ ] **Refactoring** - Code change that neither fixes a bug nor adds a feature - [x] **Build / CI** - Changes to the Maven build, CircleCI, compose, or image - [x] **Test Addition** - Adding missing tests or correcting existing tests ## Testing **How has this been tested?** - [x] **Unit Tests**: All unit tests pass - [x] **Integration Tests**: Integration tests pass - [x] **Profiles**: Checked the affected profile(s) (`core`, `full`) - [ ] **Manual Testing**: Tested manually in a development environment **Test Commands:** ```bash mvn -B -ntp verify # BUILD SUCCESS: StackBomTest 2/2; app unit tests 28 run, 0 failures, 2 skipped # (PostgresCompatibilityTest and FullProfileBrokerIntegrationTest are opt-in, as before); # failsafe 7/7 (CoreJarIT, PackagedNoticesIT) python3 -m unittest discover -s scripts -p 'test_*.py' # 45 tests OK python3 scripts/run_full_smoke.py # see below ``` Local full Compose smoke (OpenSearch 2.19.1): - The stack became healthy with `FAIL_FAST`. Quick search created `qqq-all-customers-v2-<epoch>` behind the `qqq-all-customers` alias and started its runtime service. The scheduled basepull on `demoScheduler` indexed both seeded customers with 0 errors. - The smoke then stopped at the OIDC login, before its quick-search step. QQQ's `OAuth2AuthenticationModule` threw `ClassCastException: Tokens cannot be cast to OIDCTokens`. Unchanged develop (e35f1f6) fails the same way, both locally and in CI (https://github.com/QRun-IO/qqq-all/actions/runs/37777430884), so this failure is not caused by this change. ## Checklist **Before submitting this PR, please ensure:** - [x] **Code Style**: Follows QQQ's [Code Review Standards](https://github.com/QRun-IO/qqq/wiki/Code-Review-Standards) - [x] **Tests**: All tests pass - [x] **Documentation**: Updated the README or docs where behavior changed - [x] **Secrets**: No secrets committed; any demo credentials are marked demo-only and overridable by env - [x] **Breaking Changes**: Documented any breaking changes - [x] **Commit Messages**: Follow conventional commit format - [x] **Self Review**: Code has been reviewed by the author ## Additional Information **Adoption notes** - RC.2 resolves cleanly against this stack's qqq `4.1.0-SNAPSHOT`. The BOM's qqq pin wins over the `4.1.0-RC.1` import in quick-search's default-active `qqq-snapshot` profile. opensearch-java 3.10.0, httpclient5 5.6.3 and httpcore5 5.4.3 line up. - The 0.x fluent API still compiles against RC.2, as the migration guide says. Leaving the old `addQBit` in place throws `IllegalArgumentException: Attempted to add a second qBit ... com.kingsrook.qbits:quick-search`, as the guide warns. - With the 1.0 default `FAIL_FAST`, the existing full-profile tests (OpenSearch on port 1) fail inside `defineQInstance()`. The error says to set `startupMode=DEGRADED`, which is clear and actionable. - For a table configured with `withSearchableTable` and no `modifyDate`, quick-search turns off incremental basepull without logging anything. Annotated tables log a warning in the same case. - Release gate: RC.2 builds on qbit-build-parent 2.0.0 (qqq 4.0.0 BOM) and gets 4.1.0-RC.1 through a profile. `docs/release.md` requires qbits built on a parent that imports the released QQQ version, so a quick-search build on qbit-build-parent 2.1.0 is still needed before qqq-all's release.
KofTwentyTwo commented 2026-10-08 12:36:40 +00:00 (Migrated from github.com)

CI on 24653de: CircleCI test_only passes, and Smoke core passes. Smoke full fails at the OIDC login, before its quick-search step: QQQ did not establish an OIDC session. The cause is a ClassCastException (Tokens cannot be cast to OIDCTokens) in QQQ's OAuth2AuthenticationModule.

This failure is not from this PR. A Smoke run dispatched on unchanged develop (e35f1f6) fails the same way: https://github.com/QRun-IO/qqq-all/actions/runs/37777430884. develop last passed on 2026-10-02, so the regression probably comes from a newer QQQ 4.1.0-SNAPSHOT or a newer dependency. A local run of untouched develop also fails the same way.

The diagnostics from this PR's full run show quick-search 1.0.0-RC.2 working in the stack: the quickSearch runtime service started, and the scheduled quickSearchBasepullIndex on demoScheduler indexed both seeded customers with 0 errors (https://github.com/QRun-IO/qqq-all/actions/runs/37776754631). The smoke's HTTP quickSearchFullReindex check could not run because OIDC fails first.

CI on 24653de: CircleCI `test_only` passes, and Smoke `core` passes. Smoke `full` fails at the OIDC login, before its quick-search step: `QQQ did not establish an OIDC session`. The cause is a `ClassCastException` (`Tokens` cannot be cast to `OIDCTokens`) in QQQ's `OAuth2AuthenticationModule`. This failure is not from this PR. A Smoke run dispatched on unchanged develop (e35f1f6) fails the same way: https://github.com/QRun-IO/qqq-all/actions/runs/37777430884. develop last passed on 2026-10-02, so the regression probably comes from a newer QQQ 4.1.0-SNAPSHOT or a newer dependency. A local run of untouched develop also fails the same way. The diagnostics from this PR's full run show quick-search 1.0.0-RC.2 working in the stack: the `quickSearch` runtime service started, and the scheduled `quickSearchBasepullIndex` on `demoScheduler` indexed both seeded customers with 0 errors (https://github.com/QRun-IO/qqq-all/actions/runs/37776754631). The smoke's HTTP `quickSearchFullReindex` check could not run because OIDC fails first.
This pull request has changes conflicting with the target branch.
  • infra/postgres/06-quick-search-permissions.sql
  • qqq-all-app/src/main/java/com/kingsrook/qqq/all/DemoQBits.java
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin feature/GH-29-adopt-quick-search-rc2:feature/GH-29-adopt-quick-search-rc2
git checkout feature/GH-29-adopt-quick-search-rc2
Sign in to join this conversation.