Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
8d41870
fix(driver): stop flooding logs with an ERROR stack trace per connect…
sboesebeck Aug 5, 2026
6b337d0
fix(poppydb): rs.status() now reports a dead peer as DOWN, not SECOND…
sboesebeck Aug 5, 2026
1cee138
test(failover): wire-rewriting proxy engine (FaultMode/rewriter/obser…
sboesebeck Aug 5, 2026
56067b8
fix(failover): close WireProxy.stop() race that let racing pump threa…
sboesebeck Aug 5, 2026
08303e3
test(failover): hello/isMaster address rewriter + example frame observer
sboesebeck Aug 5, 2026
a84672a
test(failover): auth-aware control channel for replSetGetStatus/replS…
sboesebeck Aug 5, 2026
e29a06c
fix(failover): ControlChannel.command throws instead of NPE on clean-…
sboesebeck Aug 5, 2026
8918bed
test(failover): DriverFailoverProxyTest harness + freeze scenario
sboesebeck Aug 5, 2026
da826be
fix(failover): join writer thread on all exit paths, drop redundant p…
sboesebeck Aug 5, 2026
89725c6
test(failover): stepdown, hard-kill, messaging and restart-after-fail…
sboesebeck Aug 5, 2026
ef6b2fc
fix(failover): guarantee thread/messaging cleanup on every exit path
sboesebeck Aug 5, 2026
349b4cf
test(failover): migrate off manual FailoverReproTest to proxy-based D…
sboesebeck Aug 5, 2026
751b746
fix(test): failover-proxy-test final-review fix wave (C2, I1-I5, minors)
sboesebeck Aug 5, 2026
198f5f5
fix(failover): worker threads must not die on a spurious interrupt
sboesebeck Aug 5, 2026
05f5ed0
fix(failover): pin serverSelectionTimeout to 5s - the 30s default let…
sboesebeck Aug 5, 2026
fec78ed
fix(failover): injectFaultOnCurrentPrimary polls for a primary instea…
sboesebeck Aug 5, 2026
06eab35
fix(failover): retry stepDown-on-stale-primary race; widen election-p…
sboesebeck Aug 5, 2026
3badcce
fix(failover): force:true on replSetStepDown - possible fix for write…
sboesebeck Aug 5, 2026
25bc70a
fix(failover): widen pollForNewPrimary to 40s - one real election too…
sboesebeck Aug 5, 2026
3d82ede
fix(failover): exclude arbiters from the driver's host-seed
sboesebeck Aug 5, 2026
4beecc5
fix(failover): reduce replSetStepDown's block window from 60s to 15s …
sboesebeck Aug 5, 2026
cb0b6d7
fix(failover): widen freeze scenario's write-recovery window to 45s f…
sboesebeck Aug 5, 2026
93a1653
fix(driver): PooledDriver adopts advertised primary immediately on st…
sboesebeck Aug 5, 2026
c7a2803
fix(failover): freeze the stepped-down primary's election eligibility…
sboesebeck Aug 5, 2026
e484cbe
debug: temporary DEBUG logging for read-stuck diagnosis (to be reverted)
sboesebeck Aug 5, 2026
c2f9694
fix(driver): borrowConnection's deadline was unreachable when the poo…
sboesebeck Aug 5, 2026
7954791
debug: revert temporary DEBUG logging (diagnosis done, root cause fou…
sboesebeck Aug 5, 2026
78ac39b
fix(failover): apply the same freezeNode protection to runWriteReadSc…
sboesebeck Aug 5, 2026
b6381fa
fix(failover): freezeNode retries instead of a single best-effort att…
sboesebeck Aug 5, 2026
b110547
fix(failover): widen runWriteReadScenario's recovery window 10s->25s
sboesebeck Aug 5, 2026
e601362
feat: add morphium-jakarta-data as optional module (#266)
Bardioc1977 Aug 5, 2026
938abdd
fix(driver): getReadConnection's NEAREST/PRIMARY_PREFERRED/SECONDARY …
sboesebeck Aug 5, 2026
4ead5fa
fix(poppydb): startup script logic fix
sboesebeck Aug 5, 2026
7fe6400
Merge remote-tracking branch 'origin/develop' into develop
sboesebeck Aug 5, 2026
9b9b272
feat: add quarkus-morphium extension as optional module
flgke81 Aug 5, 2026
b01f93b
build: register quarkus-morphium in extensions profile
flgke81 Aug 5, 2026
66effe6
docs: add quarkus extension documentation
flgke81 Aug 5, 2026
e7c869b
docs: add changelog entry for quarkus-morphium module
flgke81 Aug 5, 2026
ba7d204
build: include quarkus-morphium modules in release bundle
flgke81 Aug 5, 2026
9944c55
fix(quarkus): register all deployment build-step processors and fix n…
flgke81 Aug 5, 2026
770dde7
docs(quarkus): correct @By example — @Is(Operator) needs Jakarta Data…
flgke81 Aug 5, 2026
c23ba60
fix(quarkus): correct Antora config typo and doc/comment inaccuracies
flgke81 Aug 6, 2026
e80527d
fix(quarkus): also skip Dev Services when quarkus.morphium.atlas-url …
flgke81 Aug 6, 2026
a118b5d
fix(quarkus): resolve morphium.version from project.version, add regr…
flgke81 Aug 6, 2026
10bc870
docs(quarkus): use a placeholder password in the config example
flgke81 Aug 6, 2026
1fcac8a
fix(quarkus): actually apply quarkus.morphium.read-preference
flgke81 Aug 6, 2026
0800c9a
fix(jakarta-data): return deleted-record count from parameter-based @…
flgke81 Aug 6, 2026
2567da4
fix(quarkus): fix Gizmo VerifyError/AbstractMethodError risks in repo…
flgke81 Aug 6, 2026
11f669e
fix(jakarta-data,quarkus): honor dynamic Sort/Order/PageRequest/Limit…
flgke81 Aug 6, 2026
6e22297
fix(quarkus): catch Throwable, not Exception, so an Error still abort…
flgke81 Aug 6, 2026
842db18
fix(quarkus): retry only the commit on a transient error, never the b…
flgke81 Aug 6, 2026
bf19ac2
fix(quarkus): renew migration lock TTL between migrations, wait inste…
flgke81 Aug 6, 2026
3a8f204
fix(quarkus): guard Morphium Dev Services on Docker availability
flgke81 Aug 6, 2026
9db305f
fix(quarkus): fail fast on async return types instead of committing t…
flgke81 Aug 6, 2026
7be146b
docs(quarkus): fix nonexistent create-indexes property, add 10 missin…
flgke81 Aug 6, 2026
cd79524
fix(quarkus): register blocking-call detector's listener off the boot…
flgke81 Aug 6, 2026
9b41a6f
fix(quarkus): decouple liveness check from MongoDB connectivity
flgke81 Aug 6, 2026
9b030bb
fix(quarkus): whitelist InMemDriver for Dev Services skip, not blackl…
flgke81 Aug 6, 2026
4c82045
test(quarkus): directly verify Dev Services actually started a real r…
flgke81 Aug 6, 2026
42109fc
test(quarkus): make MorphiumStartupCheckTest exercise the real produc…
flgke81 Aug 6, 2026
a7d6939
fix(quarkus): reject partial credentials, prevent silent cache-TTL in…
flgke81 Aug 6, 2026
e379256
test(quarkus): verify malformed MorphiumId does not cause a 500 (shou…
flgke81 Aug 6, 2026
2cce8e2
fix(quarkus): broaden the no-server-transaction detection, document t…
flgke81 Aug 6, 2026
9661a62
fix(quarkus): sort migrations numerically, surface swallowed rollback…
flgke81 Aug 6, 2026
7158a04
fix(quarkus): register custom nameProvider and entity subclasses for …
flgke81 Aug 6, 2026
69d9036
docs(quarkus): fix wrong property prefix in testing.adoc, mark JAKART…
flgke81 Aug 6, 2026
c91a1da
docs(build): clarify that -DskipExtensions skips morphium-jakarta-dat…
flgke81 Aug 6, 2026
ed3cc7c
fix(jakarta-data): delete by query instead of loading and deleting en…
flgke81 Aug 6, 2026
57bfd28
docs(quarkus): fix health-checks.adoc contradicting the actual livene…
flgke81 Aug 6, 2026
e902c0a
docs(quarkus): fix @MorphiumChangeUnit#order() Javadoc contradicting …
flgke81 Aug 6, 2026
0b5fab4
fix(quarkus): make the commit retry actually retry instead of reporti…
flgke81 Aug 6, 2026
89b40b7
fix(jakarta-data,quarkus): honor the query prefix on derived methods …
flgke81 Aug 6, 2026
55b21f0
fix(quarkus): also reject Mutiny's Multi as an async return type, doc…
flgke81 Aug 6, 2026
43dbc22
fix(quarkus): stop the blocking-call detector from forcing a connect,…
flgke81 Aug 6, 2026
87b44e0
fix(quarkus): four remaining repository-codegen gaps from the blocker…
flgke81 Aug 6, 2026
58e1bad
fix(quarkus): abort on a lost migration lock, renew it during a runni…
flgke81 Aug 6, 2026
83dafb8
docs: drop internal planning markers and German comments from publish…
flgke81 Aug 6, 2026
f81e588
fix(quarkus): stop entity-parameter @Delete methods from silently del…
flgke81 Aug 7, 2026
7bbe7c7
test: make the "entity without @Version" test actually test that, plu…
flgke81 Aug 7, 2026
6137e09
fix(quarkus): disable both collection checks for CREATE_ON_WRITE_NEW_…
flgke81 Aug 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,74 @@ Each of `--auth` and `--ssl`, independently, made a multi-node PoppyDB replica s

### Added

#### Driver: automated failover test via wire-rewriting proxy, replaces manual `FailoverReproTest`
`FailoverReproTest` reproduced the 6.2.6 failover regressions but required a hand-built local
replica set and process kills (`kill -9`, SIGSTOP) run by hand — it was tagged `manual` and never
ran in CI. `DriverFailoverProxyTest` reproduces the same client-visible failure modes — clean
stepdown, hard kill, and the critical frozen-socket case (TCP connection alive but silent, the one
a driver can't distinguish from a slow server without a timeout) — plus read/write/messaging
recovery, through a reusable wire-level fault-injection proxy that sits between the driver and a
real replica set instead of killing processes. Tagged `wire-failover`, it runs automatically
against both MongoDB and PoppyDB replica sets in the normal test matrix. `FailoverReproTest` is
removed.

#### `morphium-jakarta-data` — optional Jakarta Data 1.0 runtime module
A new optional module, `morphium-jakarta-data`, brings a [Jakarta Data 1.0](https://jakarta.ee/specifications/data/1.0/)
provider implementation on top of Morphium's existing query engine: `@Repository`-based
`CrudRepository`/`MorphiumRepository` interfaces with query derivation from method names
(`findByCategory`, `countByStatus`, `deleteByX`, `And`/`Or`/`Between`/`In`/`Like`/`OrderBy`
and the rest of the standard keyword set), JDQL via `@Query` (including `GROUP BY`/`HAVING`
aggregates compiled into a Morphium aggregation pipeline), `@Find`/`@Delete` with explicit
`@By` parameter binding, offset pagination (`Page<T>`) and cursor/keyset pagination
(`CursoredPage<T>`), and both static (`@OrderBy`) and dynamic (`Sort`/`Order`) sorting. The
module depends on Morphium core and on `jakarta.data:jakarta.data-api`; the dependency
direction is strictly one-way — core has no knowledge of Jakarta Data and no dependency on
this module, so an application declaring only `de.caluga:morphium` does not get
`jakarta.data-api` on its classpath and none of these annotations or types become available.
Building the reactor with `-DskipExtensions` produces a core-only build (core + PoppyDB, no
extension modules) exactly as before this change. `morphium-jakarta-data` is deliberately
framework-agnostic — plain Java classes with zero dependencies on Quarkus, Spring, or any DI
container — because it is meant to be consumed transitively by framework integrations, not
added directly by most applications: `quarkus-morphium` (build-time Gizmo bytecode
generation) and `spring-boot-morphium` (JDK dynamic proxies) build on top of this module and
will follow in subsequent PRs. The code originates from
[Bardioc1977/morphium-jakarta-data](https://github.com/Bardioc1977/morphium-jakarta-data),
which is being archived now that its content has moved into the main Morphium repository.
See [Jakarta Data](docs/jakarta-data.md).

#### `quarkus-morphium` — optional Quarkus extension for CDI integration
A new optional module, `quarkus-morphium`, integrates Morphium into
[Quarkus](https://quarkus.io) applications: a CDI producer for `Morphium`, type-safe
runtime configuration via `@ConfigMapping` (`quarkus.morphium.*`), declarative
`@MorphiumTransactional` transactions with `MorphiumTransactionEvent` CDI events
(graceful degradation on Azure CosmosDB, auto-detected), MicroProfile liveness/readiness/
startup health checks via SmallRye Health, Dev Services (an automatically-started MongoDB
container, optionally as a single-node replica set), a Dev UI card with live connection
info, build-time Jakarta Data `@Repository` implementations generated via Gizmo bytecode
(no runtime reflection, no dynamic proxies — see [Jakarta Data](docs/jakarta-data.md) for
the underlying query-derivation, JDQL, and pagination feature set), GraalVM native-image
support (automatic reflection registration for every `@Entity`/`@Embedded` class), default
`MorphiumId` JSON serialization as its canonical 24-character hex string (both Jackson and
JSON-B, in both directions), and a MongoDB-backed migration runner with a distributed lock.
The module publishes three artifacts — `quarkus-morphium` (runtime), `quarkus-morphium-deployment`
(build-time processing), and `quarkus-morphium-testing` (test support) — plus an
`integration-tests` submodule that is built and run but never published. Like
`morphium-jakarta-data`, the core has zero compile- or runtime dependency on this module;
building the reactor with `-DskipExtensions` produces an unchanged core-only build. The
integration tests spin up a real MongoDB via Testcontainers and therefore need a running
Docker daemon — when Docker is unavailable, they detect this and skip themselves rather than
failing the build. **groupId migration:** this extension previously published under
`io.quarkiverse.morphium` as part of the Quarkiverse organization; because it does not
actually live in the [Quarkiverse](https://quarkiverse.github.io) GitHub organization,
Maven coordinates now follow Morphium's own groupId, `de.caluga:quarkus-morphium`, and
version in lockstep with the Morphium reactor. **Existing users of
`io.quarkiverse.morphium:quarkus-morphium:1.2.0` must update their dependency's groupId to
`de.caluga` and its version to the Morphium version they adopt (currently `6.3.x`)** — no
package renames, no API changes, only the Maven coordinates move. The code originates from
[Bardioc1977/quarkus-morphium](https://github.com/Bardioc1977/quarkus-morphium), which is
being archived now that its content has moved into the main Morphium repository. See
[Quarkus Extension](docs/quarkus-extension.md).

#### PoppyDB: `--users-file` — declarative user provisioning (bootstrap, upsert, version-gated)
Builds on user replication: `--rootUser`/`--rootPassword` only ever provisioned one admin user,
so any real application user set still had to be created by hand (a shell script running
Expand Down
6 changes: 4 additions & 2 deletions docs/developer-testing-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,12 +169,14 @@ The `runtests.sh` script provides a convenient wrapper around Maven with additio
--rerunfailed # Rerun only previously failed tests
```

Available tags: `core`, `messaging`, `driver`, `inmemory`, `aggregation`, `cache`, `admin`, `performance`, `encryption`, `jms`, `geo`, `util`, `external`, `manual`, `failover`
Available tags: `core`, `messaging`, `driver`, `inmemory`, `aggregation`, `cache`, `admin`, `performance`, `encryption`, `jms`, `geo`, `util`, `external`, `manual`, `failover`, `wire-failover`

Two tags have special semantics:

- `external` — the test needs a real MongoDB (CI-safe). Excluded by default; enabled by `--external` / the `-Pexternal` Maven profile.
- `manual` — the test kills processes or relies on a hardcoded local setup (e.g. `FailoverReproTest` controls a local replica set via `~/mongo`). **Never runs in CI**: excluded by default, by `-Pexternal` and by `runtests.sh`. Run explicitly via `mvn -pl morphium-core test -Dtest=<Class> -Dtest.excludeTags=`. All real failover tests (StepDown/Shutdown/process kills) carry this tag; the remaining `failover` tag only marks tests to skip on PoppyDB phases.
- `manual` — the test kills processes or relies on a hardcoded local setup. **Never runs in CI**: excluded by default, by `-Pexternal` and by `runtests.sh`. Run explicitly via `mvn -pl morphium-core test -Dtest=<Class> -Dtest.excludeTags=`. The remaining process-killing failover tests (`SingleConnectDriverFailoverTests`, `driver/pool/FailoverTests`) still carry this tag; the plain `failover` tag itself is also used as a catch-all to skip a handful of other tests on PoppyDB phases (pooled-driver tests that need a real MongoDB, `SortingTest`'s slow bulk-write case).

`wire-failover` is different: it marks `DriverFailoverProxyTest`, which reproduces failover behaviour (clean stepdown, hard kill, frozen socket, and the resulting read/write/messaging recovery) through a reusable wire-level fault-injection proxy instead of controlling a real replica set process. It needs no hardcoded local setup and kills nothing, so it **does run in the normal matrix** — against both MongoDB and PoppyDB replica sets — and is not excluded by `runtests.sh` or any Maven profile.

#### PoppyDB Options
```bash
Expand Down
15 changes: 15 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,21 @@ Morphium includes a complete in-memory MongoDB-compatible implementation for tes
## Reference
- **[API Reference](./api-reference.md)** - Complete API documentation with examples

## Extensions (Optional Modules)
Morphium's core module (`de.caluga:morphium`) is fully self-contained and does not need
any of the following. These are additional, opt-in modules built on top of the core:
- **[Jakarta Data](./jakarta-data.md)** - Optional module implementing the Jakarta Data
1.0 specification on top of Morphium's query engine (repository pattern, `@Repository`)
- Query derivation from method names, JDQL (`@Query`), `@Find`/`@Delete` with `@By`
- Offset and cursor pagination (`Page<T>`, `CursoredPage<T>`), dynamic and static sorting
- Zero dependency from the core: build with `-DskipExtensions` for a core-only artifact;
framework integrations for Quarkus and Spring Boot build on top of this module
- **[Quarkus Extension](./quarkus-extension.md)** - Optional module integrating Morphium into
Quarkus applications via a CDI producer, `@ConfigMapping`, `@MorphiumTransactional`, health
checks, Dev Services, Dev UI, and build-time Jakarta Data repository generation via Gizmo
- GraalVM native-image support and `MorphiumId` JSON (de)serialization out of the box
- Zero dependency from the core: build with `-DskipExtensions` for a core-only artifact

Minimum requirements
- Java 21+
- MongoDB 5.0+
Expand Down
Loading