From aa202422d43b6ccefd3a4b887fe032dcd71bf1fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Kobyli=C5=84ski?= Date: Wed, 12 Aug 2026 09:48:59 +0200 Subject: [PATCH 1/4] docs: refresh README for 1.0 --- CHANGELOG.md | 6 +- README.md | 424 ++++++++++++++-------------------- UPGRADING.md | 55 +++++ docs/images/okapi-modules.png | Bin 0 -> 135862 bytes 4 files changed, 232 insertions(+), 253 deletions(-) create mode 100644 UPGRADING.md create mode 100644 docs/images/okapi-modules.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 3728fe8..edcfce7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -138,10 +138,8 @@ only ship in a new major version. ### Migration from 0.2.x -Breaking — existing deployments must act before the first `0.3.0` startup. Full SQL is in -the README: [Database migrations § Upgrading from 0.2.x](README.md#upgrading-from-02x). -Rename the domain table in place (no opt-out), and either adopt the new Liquibase -tracking-table names or override them back to the legacy ones. +Existing deployments upgrading directly from 0.2.x to 1.0.0 must complete the steps in +[UPGRADING.md](UPGRADING.md) before starting the new version. ## [0.2.0] — 2026-04-29 diff --git a/README.md b/README.md index 7ff6273..a907ae7 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,46 @@ -# Okapi +# okapi -[![Ideas, suggestions, problems, questions](https://img.shields.io/badge/Discourse-ask%20question-blue)](https://softwaremill.community/c/open-source/11) +[![Maven Central](https://img.shields.io/maven-central/v/com.softwaremill.okapi/okapi-core?label=maven%20central&color=blue)](https://central.sonatype.com/artifact/com.softwaremill.okapi/okapi-core) [![CI](https://github.com/softwaremill/okapi/workflows/CI/badge.svg)](https://github.com/softwaremill/okapi/actions?query=workflow%3A%22CI%22) [![Kotlin](https://img.shields.io/badge/dynamic/toml?url=https%3A%2F%2Fraw.githubusercontent.com%2Fsoftwaremill%2Fokapi%2Frefs%2Fheads%2Fmain%2Fgradle%2Flibs.versions.toml&query=%24.versions.kotlin&logo=kotlin&label=kotlin&color=blue)](https://kotlinlang.org) [![JVM](https://img.shields.io/badge/JVM-21-orange.svg?logo=openjdk)](https://www.java.com) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE) +[![Ask a question](https://img.shields.io/badge/Discourse-ask%20question-blue)](https://softwaremill.community/c/open-source/11) -Kotlin library implementing the **transactional outbox pattern** — reliable message delivery alongside local database operations. +**Reliable message delivery for Kotlin and Java services, using the transactional outbox pattern.** -Messages are stored in a database table within the same transaction as your business operation, then asynchronously delivered to external transports (HTTP webhooks, Kafka). This guarantees **at-least-once delivery** without distributed transactions. +When your service saves something to the database and then has to notify another service, publish an event, or call a webhook, those two steps don't share a transaction. If you commit first, a crash or a network blip loses the notification. If you call the downstream inside the transaction, its latency and its failures become yours. -## Quick Start (Spring Boot) +okapi closes that gap: the message is written to an outbox table **inside your business transaction**, and a background processor delivers it afterwards, retrying on failure. -Add dependencies using the BOM for version alignment: +- **Storage**: PostgreSQL, MySQL 8+ +- **Transports**: HTTP webhooks, Kafka +- **Frameworks**: Spring Boot autoconfiguration, or wire it by hand anywhere on the JVM +- **Kotlin-first**, with a Java-friendly API +- **Apache-2.0**, JDK 21+ + +--- + +## Quick start (Spring Boot) + +This example assumes an existing Spring Boot application connected to PostgreSQL, with a configured `DataSource` and `PlatformTransactionManager`. + +**1. Add the dependencies.** The BOM keeps module versions aligned: ```kotlin dependencies { - implementation(platform("com.softwaremill.okapi:okapi-bom:$okapiVersion")) + implementation(platform("com.softwaremill.okapi:okapi-bom:1.0.0")) implementation("com.softwaremill.okapi:okapi-core") implementation("com.softwaremill.okapi:okapi-postgres") implementation("com.softwaremill.okapi:okapi-http") implementation("com.softwaremill.okapi:okapi-spring-boot") + runtimeOnly("org.liquibase:liquibase-core") } ``` -Provide a `MessageDeliverer` bean — this tells okapi how to deliver messages. -`ServiceUrlResolver` maps the logical service name (set per message) to a base URL: +Liquibase creates the `okapi_outbox` table on startup — no changelog edits on your side. See [Database schema](#database-schema). + +**2. Provide a deliverer bean.** This example uses HTTP. `ServiceUrlResolver` maps a logical service name to a base URL, so deployment topology stays out of your publishing code: ```kotlin @Bean @@ -38,354 +53,265 @@ fun httpDeliverer(): HttpMessageDeliverer = }) ``` -Publish inside any `@Transactional` method — inject `SpringOutboxPublisher` via constructor: +**3. Publish inside your transaction.** Inject `SpringOutboxPublisher` and call it right after your business write: ```kotlin @Service class OrderService( private val orderRepository: OrderRepository, - private val springOutboxPublisher: SpringOutboxPublisher + private val outboxPublisher: SpringOutboxPublisher, ) { @Transactional fun placeOrder(order: Order) { orderRepository.save(order) - springOutboxPublisher.publish( + + outboxPublisher.publish( OutboxMessage("order.created", order.toJson()), httpDeliveryInfo { serviceName = "notification-service" endpointPath = "/webhooks/orders" - } + }, ) } } ``` -Autoconfiguration handles scheduling, retries, and delivery automatically. For Micrometer metrics, also add `okapi-micrometer` — see [Observability](#observability). +The order row and the outbox row now commit together or not at all. Autoconfiguration takes care of scheduling, retries, delivery and cleanup. -**Using Kafka instead of HTTP?** Swap the deliverer bean and delivery info: +> `SpringOutboxPublisher` throws `IllegalStateException` if you call `publish()` outside an active read-write transaction. That is deliberate — an outbox write that can't commit atomically with your business data defeats the purpose of the pattern. -```kotlin -@Bean -fun kafkaDeliverer(producer: KafkaProducer): KafkaMessageDeliverer = - KafkaMessageDeliverer(producer) -``` -```kotlin -springOutboxPublisher.publish( - OutboxMessage("order.created", order.toJson()), - kafkaDeliveryInfo { topic = "order-events" } -) -``` +## How it works -**Using MySQL instead of PostgreSQL?** Replace `okapi-postgres` with `okapi-mysql` in your dependencies — no code changes needed. Add `rewriteBatchedStatements=true` to your JDBC URL — see [Performance](#performance) for why. +1. `publish()` writes a `PENDING` row to `okapi_outbox` in your transaction. +2. A background scheduler polls for pending rows (every second by default), claiming them with `FOR UPDATE SKIP LOCKED` so workers do not process the same row concurrently. +3. Each row goes to the transport matching its delivery type. Success marks it `DELIVERED`; a retriable failure leaves it `PENDING` while retry attempts remain; an exhausted retry budget or permanent failure marks it `FAILED`. +4. A purger deletes delivered rows after a retention period. -> **Note:** Spring and Kafka versions are not forced by okapi — you control them. -> Okapi uses plain JDBC internally — it works with any `PlatformTransactionManager` (JPA, JDBC, jOOQ, Exposed, etc.). +### Guarantees and limits -`okapi-spring-boot` requires a `TransactionRunner` bean to bracket each scheduler tick in a transaction. The autoconfiguration derives one from any `PlatformTransactionManager` on the classpath (`spring-boot-starter-jdbc` or `spring-boot-starter-data-jpa` provide one out of the box) — no extra wiring needed in typical setups. If your application has no `PlatformTransactionManager` (single-instance, no transaction infrastructure) you must opt in explicitly: +- **Duplicate delivery is possible.** A crash between a successful delivery and the status update means the message may be sent again after restart. If processing a message more than once would cause unwanted effects, make the consumer idempotent — for example, deduplicate on a business key in the payload or a header set in the `DeliveryInfo`. okapi sends your payload and configured headers, but not the `OutboxId` returned by `publish()`; that identifier stays on the publisher side for correlation and logging. +- **Best-effort ordering.** Rows are claimed by `created_at`, oldest first. However, parallel delivery and retries mean messages may reach consumers in a different order. Strict delivery ordering is not guaranteed. +- **Failure classification is the transport's job.** Each deliverer decides what is retriable. HTTP: 5xx, 429, 408 and connection errors are retriable; other responses and TLS errors are permanent. Kafka: broker-side retriable exceptions are retried; authorization and configuration errors are not. +- **Retry budget.** `okapi.processor.max-retries` (default 5) counts retries *after* the first attempt — six attempts in total before a row becomes `FAILED`. `FAILED` is terminal. Retriable messages become eligible again on the next processor poll; there is no per-message backoff. -```kotlin -@Bean -fun outboxTransactionRunner(): TransactionRunner = object : TransactionRunner { - override fun runInTransaction(block: () -> T): T = block() -} -``` +## Configuration -Without a `TransactionRunner` each scheduler tick runs in auto-commit, which can cause duplicate delivery across instances — see Advanced below. +In a typical single-DataSource application, all properties are optional. Multi-DataSource setups may require explicit qualifiers, as described below. -Advanced setups — multiple DataSources, JTA/Exposed PTMs, qualifier precedence — see [Advanced: transactions & multi-DataSource](#advanced-transactions--multi-datasource) below. +### Processor -## Advanced: transactions & multi-DataSource +| Property | Default | Description | +|---|---|---| +| `okapi.processor.enabled` | `true` | Set `false` to disable delivery entirely (e.g. on instances that only publish). | +| `okapi.processor.interval` | `1s` | How often the scheduler polls for pending entries. | +| `okapi.processor.batch-size` | `10` | Maximum entries claimed per worker per tick. | +| `okapi.processor.max-retries` | `5` | Retries after the initial attempt before an entry becomes `FAILED`. | +| `okapi.processor.concurrency` | `1` | Parallel workers per tick, each claiming its own batch. Tune based on database capacity and delivery latency; see [Performance](#performance). | -Without bracketing, `FOR UPDATE SKIP LOCKED` collapses to the single SELECT statement under JDBC auto-commit, which silently allows duplicate delivery across processor instances. This opt-in is intentionally manual to keep accidental misconfiguration out of multi-instance deployments. +### Purger -**Multi-DataSource contexts.** If your application has multiple `DataSource` beans and uses a `PlatformTransactionManager` from which okapi cannot extract a `DataSource` (JTA, Exposed's `SpringTransactionManager`, JPA without a JDBC `DataSource`), the autoconfiguration refuses to start until you set `okapi.transaction-manager-qualifier` to the bean name of the PTM that brackets the outbox `DataSource`. `okapi.datasource-qualifier` alone is not sufficient: it picks the outbox `DataSource` but does not constrain which PTM brackets it. Alternative escape hatch: supply your own `@Bean TransactionRunner`. Single-DataSource setups and PTMs whose `DataSource` can be introspected (`DataSourceTransactionManager`, `JpaTransactionManager`, `HibernateTransactionManager`) are unaffected. +Delivered entries are deleted on a schedule so they do not accumulate. `FAILED` entries are never purged and must be managed separately. -When `okapi.transaction-manager-qualifier` is set, it takes precedence over any auto-wired `TransactionTemplate` — including the one Spring Boot's `TransactionAutoConfiguration` registers around the `@Primary` `PlatformTransactionManager`. If the qualifier names a different PTM than that auto-TT wraps, okapi builds a fresh `TransactionTemplate` around the qualified PTM (so the qualifier's intent is honoured) and any custom timeout/isolation/propagation on the auto-wired TT is not inherited — a WARN is logged in that case. +| Property | Default | Description | +|---|---|---| +| `okapi.purger.enabled` | `true` | Set `false` to manage retention yourself (partitioning, external cron). | +| `okapi.purger.retention` | `7d` | How long delivered entries are kept. | +| `okapi.purger.interval` | `1h` | How often the purger runs. | +| `okapi.purger.batch-size` | `100` | Rows deleted per batch; each batch is its own transaction. | -**Constructing schedulers directly (non-autoconfig usage).** When wiring `OutboxProcessorScheduler` / `OutboxPurgerScheduler` manually (Ktor, custom Spring contexts without autoconfig, etc.), supply a `TransactionRunner` explicitly — the parameter is required, with no default: +### Schema -```kotlin -OutboxProcessorScheduler( - outboxProcessor = processor, - transactionRunner = SpringTransactionRunner(template), // or your framework's equivalent - config = OutboxSchedulerConfig(...), -) -``` +| Property | Default | Description | +|---|---|---| +| `okapi.liquibase.enabled` | `true` | Set `false` if your application manages the outbox schema itself. | +| `okapi.liquibase.changelog-table` | `okapi_databasechangelog` | Liquibase tracking table for okapi's migrations. | +| `okapi.liquibase.changelog-lock-table` | `okapi_databasechangeloglock` | Liquibase lock table for okapi's migrations. | -## How It Works +### Data source and transactions -Okapi implements the [transactional outbox pattern](https://softwaremill.com/microservices-101/) (see also: [microservices.io description](https://microservices.io/patterns/data/transactional-outbox.html)): +| Property | Default | Description | +|---|---|---| +| `okapi.datasource-qualifier` | unset | Bean name of the outbox `DataSource`. When unset, the single or `@Primary` `DataSource` is used. | +| `okapi.transaction-manager-qualifier` | unset | Bean name of the outbox `PlatformTransactionManager`. When unset, it is resolved automatically. Set explicitly in multi-PTM setups — see [Transactions](#transactions). | -1. Your application writes an `OutboxMessage` to the outbox table **in the same database transaction** as your business operation -2. A background `OutboxScheduler` polls for pending messages and delivers them to the configured transport (HTTP, Kafka) -3. Failed deliveries are retried according to a configurable `RetryPolicy` (max attempts, backoff) +### Metrics -**Delivery guarantees:** +| Property | Default | Description | +|---|---|---| +| `okapi.metrics.enabled` | `true` | Set `false` to disable okapi's Micrometer autoconfiguration. Logs a startup warning when disabled. | +| `okapi.metrics.refresh-interval` | `15s` | How often gauges poll the store. Each refresh runs two queries, wrapped in a single read-only transaction when a transaction manager is available. | -- **At-least-once delivery** — okapi guarantees every message will be delivered, but duplicates are possible (e.g., after a crash between delivery and status update). Consumers should handle idempotency, for example by checking the `OutboxId` returned by `publish()`. -- **Concurrent processing** — multiple processors can run in parallel using `FOR UPDATE SKIP LOCKED`, so messages are never processed twice simultaneously. -- **Delivery result classification** — each transport classifies errors as `Success`, `RetriableFailure`, or `PermanentFailure`. For example, HTTP 429 is retriable while HTTP 400 is permanent. +## Storage and transports -## Database migrations +### MySQL -Okapi ships Liquibase changelogs that create the outbox table and its indexes: +Replace `okapi-postgres` with `okapi-mysql`; the okapi publishing API stays the same. Add `rewriteBatchedStatements=true` to your JDBC URL (`jdbc:mysql://host:3306/db?rewriteBatchedStatements=true`) so Connector/J can send a JDBC batch as a single multi-statement request. okapi cannot set this for you, since it doesn't own your `DataSource`. -- `classpath:com/softwaremill/okapi/db/postgres/changelog.xml` — PostgreSQL (from `okapi-postgres`) -- `classpath:com/softwaremill/okapi/db/mysql/changelog.xml` — MySQL (from `okapi-mysql`) +### Kafka -When `okapi-spring-boot` is on the classpath, these run automatically against the configured `DataSource` on application startup. Without Spring Boot, point your own Liquibase setup at the paths above and pass an `outboxTable` change-log parameter (see below). +Provide a `KafkaMessageDeliverer` bean with your own producer, and publish with the matching builder: -### Configuration +```kotlin +@Bean +fun kafkaDeliverer(producer: KafkaProducer): KafkaMessageDeliverer = + KafkaMessageDeliverer(producer) +``` -Okapi's table names are fixed under the `okapi_` prefix so its schema stays out of the way of any pre-existing tables in the host application (`outbox`, `databasechangelog`, etc.): +```kotlin +outboxPublisher.publish( + OutboxMessage("order.created", order.toJson()), + kafkaDeliveryInfo { topic = "order-events" }, +) +``` -| Table | Purpose | -|-------|---------| -| `okapi_outbox` | Domain table holding outbox entries (created by the bundled Liquibase changesets, queried by `PostgresOutboxStore` / `MysqlOutboxStore`). | -| `okapi_databasechangelog` | Liquibase changeset history for okapi (configurable). | -| `okapi_databasechangeloglock` | Liquibase concurrency lock for okapi (configurable). | +You can register HTTP and Kafka deliverers together; okapi routes each entry by delivery type. You provide and configure the Kafka producer. -The Liquibase tracking-table names are configurable in case the host application wants to share them with its own Liquibase setup: +## Without Spring Boot -| Property | Default | Description | -|----------|---------|-------------| -| `okapi.liquibase.changelog-table` | `okapi_databasechangelog` | Liquibase changeset history for okapi | -| `okapi.liquibase.changelog-lock-table` | `okapi_databasechangeloglock` | Liquibase concurrency lock for okapi | +`okapi-core` has no framework dependencies, so any JVM service can use it, from a Ktor app to a background worker. You assemble the pieces yourself — create the store, the deliverer, and the processor, start an `OutboxScheduler`, and hand it a `TransactionRunner` (a one-method interface wrapping a block in whatever transaction mechanism you already use). Copy the database-specific SQL linked in [Database schema](#database-schema) into your application's migrations. -These properties affect the autoconfigured `okapiPostgresLiquibase` / `okapiMysqlLiquibase` beans only. If you run Liquibase yourself, configure the table names there directly. The domain table name (`okapi_outbox`) is fixed. +### Exposed -### Upgrading from 0.2.x +`okapi-exposed` bridges okapi's transaction and connection abstractions to Exposed: `ExposedTransactionRunner`, `ExposedTransactionContextValidator`, and `ExposedConnectionProvider`. Useful for Ktor and standalone Kotlin services. -Releases up to 0.2.x wrote to shared tables `databasechangelog` / `databasechangeloglock` and the domain table `outbox`. From 0.3.0 these are renamed to `okapi_*`. Two upgrade paths: +## Database schema -**Stay on the existing changelog tables** (simplest for the Liquibase tracking pair, zero-downtime) — opt out of the new defaults: +okapi ships Liquibase changelogs that create its table and indexes: -```yaml -okapi: - liquibase: - changelog-table: databasechangelog - changelog-lock-table: databasechangeloglock -``` +- `classpath:com/softwaremill/okapi/db/postgres/changelog.xml` (from `okapi-postgres`) +- `classpath:com/softwaremill/okapi/db/mysql/changelog.xml` (from `okapi-mysql`) -The domain table `outbox` cannot be opted out via configuration — see the migration steps below. +With `okapi-spring-boot` and Liquibase on the classpath, these run automatically against the configured `DataSource` at startup, tracked in dedicated Liquibase tables by default to avoid conflicts with the application's migration history. -**Migrate to dedicated tables** — run before the first 0.3.0 startup (PostgreSQL syntax shown): +If you use another migration tool, copy the SQL for your database into your application's migrations: -```sql --- Outbox domain table: rename in place. Indexes follow the table. -ALTER TABLE outbox RENAME TO okapi_outbox; -ALTER INDEX idx_outbox_status_last_attempt RENAME TO idx_okapi_outbox_status_last_attempt; -ALTER INDEX idx_outbox_status_created_at RENAME TO idx_okapi_outbox_status_created_at; +- [PostgreSQL SQL](okapi-postgres/src/main/resources/com/softwaremill/okapi/db/postgres/001__create_okapi_outbox_table.sql) +- [MySQL SQL](okapi-mysql/src/main/resources/com/softwaremill/okapi/db/mysql/001__create_okapi_outbox_table.sql) --- Liquibase tracking: split okapi rows into the new tables. -CREATE TABLE okapi_databasechangelog (LIKE databasechangelog INCLUDING ALL); -CREATE TABLE okapi_databasechangeloglock (LIKE databasechangeloglock INCLUDING ALL); -INSERT INTO okapi_databasechangelog - SELECT * FROM databasechangelog WHERE filename LIKE '%com/softwaremill/okapi/%'; -INSERT INTO okapi_databasechangeloglock SELECT * FROM databasechangeloglock; -DELETE FROM databasechangelog WHERE filename LIKE '%com/softwaremill/okapi/%'; -``` +okapi stores messages in the fixed `okapi_outbox` table. When the built-in Liquibase integration is used, it also uses two dedicated migration tracking tables: + +| Table | Purpose | +|---|---| +| `okapi_outbox` | Outbox entries. Name is fixed. | +| `okapi_databasechangelog` | Liquibase history for okapi's migrations (configurable; Liquibase integration only). | +| `okapi_databasechangeloglock` | Liquibase lock for okapi's migrations (configurable; Liquibase integration only). | + +## Transactions -Without one of these steps, Liquibase will see an empty changelog table on the first 0.3.0 startup and try to re-run okapi's migrations — which fails if rows already exist under the legacy `outbox` table while okapi now writes to `okapi_outbox`. +Each processor worker runs its claim, delivery and state update inside one transaction, which keeps `FOR UPDATE SKIP LOCKED` active until delivery state is saved. Each purge batch also runs in its own transaction. With a single `DataSource` and `PlatformTransactionManager`, no additional transaction configuration is needed. -Full release history: [CHANGELOG.md](CHANGELOG.md). +**Multiple data sources or transaction managers?** Set both `okapi.datasource-qualifier` and `okapi.transaction-manager-qualifier` to the beans used for the outbox. okapi fails fast when it detects a mismatch. If the selected transaction manager does not expose its `DataSource`, okapi cannot verify the pairing and logs a warning instead. + +**Wiring schedulers by hand?** `TransactionRunner` is a required constructor parameter, with no default: + +```kotlin +OutboxScheduler( + outboxProcessor = processor, + transactionRunner = transactionRunner, + config = OutboxSchedulerConfig(...), +) +``` ## Observability -Add `okapi-micrometer` alongside `okapi-spring-boot` (from the Quick Start above) to get Micrometer metrics: +For Spring Boot metrics with Prometheus, add: ```kotlin implementation("com.softwaremill.okapi:okapi-micrometer") +implementation("org.springframework.boot:spring-boot-starter-actuator") +runtimeOnly("io.micrometer:micrometer-registry-prometheus") +``` + +Expose the Prometheus endpoint: + +```yaml +management: + endpoints: + web: + exposure: + include: health,prometheus ``` -With Spring Boot Actuator and a Prometheus registry (`micrometer-registry-prometheus`) on the classpath, metrics are automatically exposed on `/actuator/prometheus`. They are also visible via `/actuator/metrics`. +Metrics are then available at `/actuator/prometheus`. | Metric | Type | Description | -|--------|------|-------------| +|---|---|---| | `okapi.entries.delivered` | Counter | Successfully delivered entries | | `okapi.entries.retry.scheduled` | Counter | Failed attempts rescheduled for retry | | `okapi.entries.failed` | Counter | Permanently failed entries | | `okapi.batch.duration` | Timer | Processing time per batch | -| `okapi.entries.count` | Gauge | Current entry count (tag: `status=pending\|delivered\|failed`) | -| `okapi.entries.lag.seconds` | Gauge | Age of oldest entry in seconds (tag: `status`) | +| `okapi.entries.count` | Gauge | Current entry count (tag: `status`) | +| `okapi.entries.lag.seconds` | Gauge | Age of the oldest entry (tag: `status`) | -### Configuration - -| Property | Default | Description | -|----------|---------|-------------| -| `okapi.metrics.refresh-interval` | `PT15S` (15s) | How often gauge metrics poll the outbox store. Each refresh runs one transaction with two queries. | -| `okapi.metrics.enabled` | `true` | Set `false` to disable `okapi-micrometer` entirely — no counters, timers, gauges, or store polling. Logs a startup warning when disabled. | - -### Multi-instance deployments - -Counters and timers (`okapi.entries.delivered`, `okapi.entries.retry.scheduled`, `okapi.entries.failed`, `okapi.batch.duration`) report work performed by **each instance** — aggregate with `sum`: +**Aggregating across instances.** Counters and timers are per-instance, so sum them: ```promql -sum(rate(okapi_entries_delivered_total[5m])) +sum by (job) (rate(okapi_entries_delivered_total[5m])) ``` -Gauges (`okapi.entries.count`, `okapi.entries.lag.seconds`) reflect the **shared outbox state** and are reported identically by every instance. Aggregate with `max by (status)`, not `sum`: +Gauges represent shared database state and are emitted by every instance. Do not sum them across instances; aggregate by Prometheus job and status: ```promql -max by (status) (okapi_entries_count) -``` - -Polling cost per instance is `2 queries / okapi.metrics.refresh-interval` (default `2 queries / 15s`). - -### Without Spring Boot - -`okapi-micrometer` has no Spring dependency. Construct the beans manually and pass a `MeterRegistry`. `MicrometerOutboxMetrics` requires a `TransactionRunner` for Exposed-backed stores — see the class KDoc. - -For periodic gauge refresh, use the framework-agnostic `OutboxMetricsRefresher` (single daemon thread): - -```kotlin -val listener = MicrometerOutboxListener(meterRegistry) -val metrics = MicrometerOutboxMetrics(store, meterRegistry, transactionRunner) - -val refresher = OutboxMetricsRefresher(metrics, Duration.ofSeconds(15)) -refresher.start() -// on application shutdown: -refresher.close() +max by (job, status) (okapi_entries_count) ``` -Or call `metrics.refresh()` from your own scheduler (Ktor coroutine, `ScheduledExecutorService`, etc.) — `refresh()` is thread-safe. - -### Custom listener +Without Spring Boot, construct `MicrometerOutboxListener` and `MicrometerOutboxMetrics` with your `MeterRegistry`. Refresh gauges with `OutboxMetricsRefresher` or your own scheduler. -Implement `OutboxProcessorListener` to react to delivery events (logging, alerting, custom metrics). `OutboxProcessor` accepts a single listener; to combine multiple, implement a composite that delegates to each. +For custom reactions to delivery events, implement `OutboxProcessorListener`. `OutboxProcessor` takes a single listener; combine several with a composite of your own. ## Modules -```mermaid -graph BT - PG[okapi-postgres] --> CORE[okapi-core] - MY[okapi-mysql] --> CORE - HTTP[okapi-http] --> CORE - KAFKA[okapi-kafka] --> CORE - MICRO[okapi-micrometer] --> CORE - EXP[okapi-exposed] --> CORE - SPRING[okapi-spring-boot] --> CORE - SPRING -.->|compileOnly| PG - SPRING -.->|compileOnly| MY - SPRING -.->|compileOnly| MICRO - BOM[okapi-bom] - - style CORE fill:#4a9eff,color:#fff - style BOM fill:#888,color:#fff -``` +The runtime modules build on `okapi-core`; `okapi-bom` only aligns their versions. Pick a storage module, one or more transports, and a framework adapter if you want one. + +[![Okapi module architecture](docs/images/okapi-modules.png)](https://softwaremill.com/transactional-outbox-with-okapi/) | Module | Purpose | -|--------|---------| -| `okapi-core` | Transport/storage-agnostic orchestration, scheduling, retry policy, `ConnectionProvider` interface | -| `okapi-exposed` | Exposed ORM integration — `ExposedConnectionProvider`, `ExposedTransactionRunner`, `ExposedTransactionContextValidator` | +|---|---| +| `okapi-core` | Abstractions, processing loop, scheduling, retry policy. No framework dependencies. | | `okapi-postgres` | PostgreSQL storage via plain JDBC (`FOR UPDATE SKIP LOCKED`) | | `okapi-mysql` | MySQL 8+ storage via plain JDBC | -| `okapi-http` | HTTP webhook delivery (JDK HttpClient) | +| `okapi-http` | HTTP webhook delivery (JDK `HttpClient`) | | `okapi-kafka` | Kafka topic publishing | -| `okapi-micrometer` | Micrometer metrics (counters, timers, gauges) | -| `okapi-spring-boot` | Spring Boot autoconfiguration (auto-detects store, transports, and metrics) | -| `okapi-bom` | Bill of Materials for version alignment | +| `okapi-spring-boot` | Spring Boot autoconfiguration — selects a store module and wires registered deliverers and metrics | +| `okapi-exposed` | Exposed ORM integration for transactions and connections | +| `okapi-micrometer` | Micrometer counters, timers and gauges | +| `okapi-bom` | Version alignment for all of the above | ## Compatibility -| Dependency | Supported Versions | Notes | +| Dependency | Supported | Notes | |---|---|---| | Java | 21+ | Required | -| Spring Boot | 3.5.x, 4.0.x | `okapi-spring-boot` module | -| Kafka Clients | 3.9.x, 4.x | `okapi-kafka` — you provide `kafka-clients` | -| Exposed | 1.x | `okapi-exposed` module — for Ktor/standalone apps | +| Spring Boot | 3.5.x, 4.0.x | `okapi-spring-boot` | +| Kafka Clients | 3.9.x, 4.x | Included transitively by `okapi-kafka`; you can override the version in your build. | +| Exposed | 1.x | `okapi-exposed` | -## Performance +The storage modules use plain JDBC. With Spring Boot, they participate in the transaction selected through a `PlatformTransactionManager`; `okapi-exposed` provides adapters for Exposed-managed transactions. -Throughput on a single instance (MacBook M3 Max, JDK 21 LTS, May 2026): - -| Transport | batchSize=10 | batchSize=100 | -|-----------|--------------|----------------| -| Kafka (`acks=all`, localhost broker, async batch via `deliverBatch`) | **~1,790 msg/s** | **~5,180 msg/s** | -| HTTP @ webhook latency 20 ms (sync sequential — parallel `sendAsync` planned) | ~38 msg/s | ~38 msg/s | -| HTTP @ webhook latency 100 ms (sync sequential — parallel `sendAsync` planned) | ~9 msg/s | ~9 msg/s | - -Kafka throughput jumped 16-45× over the original sync-sequential baseline thanks to the `deliverBatch` fire-flush-await pattern. HTTP parallel `sendAsync` is next. +## Performance -**Multi-threaded scheduler** (`OutboxSchedulerConfig.concurrency`, JDK 25, single Postgres+Kafka backend): +Performance depends on the selected transport, database, batch size, concurrency and downstream latency. See [`benchmarks/`](benchmarks/) for methodology and measured results. -| concurrency | speedup vs. concurrency=1 | -|---|---| -| 4 | **3.6×** | -| 16 | **6.2×** | -| 64 | **6.6×** (diminishing — see caveats below) | - -`concurrency=4` to `16` is the practical sweet spot — most of the available speedup is already -captured there, with marginal gains beyond it on a single-instance backend. Default to platform -threads (`workerExecutorFactory` default): in this benchmark's tested range (1-64 workers), -switching to `virtualThreadPool` showed **no measurable advantage** over platform threads, even -on a JEP 491 JDK (25) — contrary to the original hypothesis that virtual threads would win at -concurrency=16+. Virtual threads only pay off when worker count vastly exceeds the platform pool -size; at ≤64 workers there's no oversubscription for them to fix. Tuning rule of thumb: -`concurrency × instances ≤ max_connections / 2` (row locks make cross-instance coordination free -via `FOR UPDATE SKIP LOCKED`, but every worker holds a DB connection for its batch's duration). - -Full methodology, raw JMH results, before/after per change: [`benchmarks/`](benchmarks/), including -[`results-postopt-KOJAK-77.md`](benchmarks/results-postopt-KOJAK-77.md) for the full concurrency -breakdown and the reasoning behind the virtual-thread finding. - -### MySQL: `rewriteBatchedStatements` - -`OutboxStore.updateAfterProcessingBatch()` writes back a whole processed batch via one JDBC -`executeBatch()` call. On Postgres, PgJDBC pipelines batched statements over the wire natively, so -this already collapses N roundtrips into ~1. **MySQL Connector/J does not** — by default it sends -one roundtrip per statement in the batch regardless of `addBatch()`/`executeBatch()`, silently -negating the optimization. Add `rewriteBatchedStatements=true` to the JDBC URL -(`jdbc:mysql://host:3306/db?rewriteBatchedStatements=true`) so Connector/J rewrites the batch into -a single multi-statement round trip. This is a driver/connection setting — okapi cannot set it for -you since it doesn't own your `DataSource`. - -We verified the rewrite genuinely happens (Connector/J's own query profiler confirms a batch of -1000 `UPDATE`s becomes one multi-statement round trip), but couldn't measure a net speedup from it -in our benchmark — see -[`results-mysql-rewrite-batched-statements.md`](benchmarks/results-mysql-rewrite-batched-statements.md) -for why (a client-side response-decoding cost that scales with batch size). We still recommend -enabling it — the round-trip savings are real and matter most against a network-hosted MySQL — but -unlike Postgres's measured 10.2×, we don't have a MySQL multiplier to back it with. - -Full methodology, raw JMH results, before/after per change: [`benchmarks/`](benchmarks/), including -[`results-postopt-KOJAK-75.md`](benchmarks/results-postopt-KOJAK-75.md) for the batch-UPDATE -numbers above. - -## Build +## Building ```sh -./gradlew build # Build all modules -./gradlew test # Run tests (Docker required — Testcontainers) -./gradlew ktlintFormat # Format code +./gradlew build # Build and test all modules (Docker required — Testcontainers) +./gradlew ktlintFormat # Format code — mandatory before committing ./gradlew :okapi-benchmarks:jmh # Run JMH benchmarks (~30 min, see benchmarks/README.md) ``` -Requires JDK 21. - ## Contributing -All suggestions welcome :) - -To compile and test, run: - -```sh -./gradlew build -./gradlew ktlintFormat # Mandatory before committing -``` - -See the list of [issues](https://github.com/softwaremill/okapi/issues) and pick one! Or report your own. - -If you are having doubts on the _why_ or _how_ something works, don't hesitate to ask a question on [Discourse](https://softwaremill.community/c/open-source/11) or via GitHub. This probably means that the documentation or code is unclear and can be improved for the benefit of all. +All suggestions are welcome. Take a look at the [open issues](https://github.com/softwaremill/okapi/issues) and pick one, or report your own. -Tests use [Testcontainers](https://www.testcontainers.org/) — Docker must be running. +If you are unsure *why* or *how* something works, ask on [Discourse](https://softwaremill.community/c/open-source/11) or open an issue. That usually means the documentation or the code is unclear, and fixing it helps everyone. -When you have a PR ready, take a look at our ["How to prepare a good PR" guide](https://softwaremill.community/t/how-to-prepare-a-good-pr-to-a-library/448). Thanks! :) +When your PR is ready, see our [guide to preparing a good PR](https://softwaremill.community/t/how-to-prepare-a-good-pr-to-a-library/448). -## Project sponsor +## Commercial support -We offer commercial development services. [Contact us](https://softwaremill.com) to learn more about us! +okapi is built and maintained by [SoftwareMill](https://softwaremill.com). We offer commercial development services — [get in touch](https://softwaremill.com) to learn more. -## Copyright +## License -Copyright (C) 2026 SoftwareMill [https://softwaremill.com](https://softwaremill.com). +Copyright (C) 2026 SoftwareMill. Licensed under the [Apache License 2.0](LICENSE). diff --git a/UPGRADING.md b/UPGRADING.md new file mode 100644 index 0000000..b92aabd --- /dev/null +++ b/UPGRADING.md @@ -0,0 +1,55 @@ +# Upgrading + +This guide contains actions required when upgrading between incompatible okapi versions. +For the full release history, see [CHANGELOG.md](CHANGELOG.md). + +## From 0.2.x to 1.0.0 + +Releases up to 0.2.x used the domain table `outbox` and the shared Liquibase tracking +tables `databasechangelog` and `databasechangeloglock`. Later versions use +`okapi_outbox` and dedicated Liquibase tracking tables by default. + +Stop all okapi processors and complete the following steps before starting 1.0.0. + +### PostgreSQL + +Rename the table and its indexes in place. The rows, including pending messages, are +preserved. + +```sql +ALTER TABLE outbox RENAME TO okapi_outbox; +ALTER INDEX idx_outbox_status_last_attempt RENAME TO idx_okapi_outbox_status_last_attempt; +ALTER INDEX idx_outbox_status_created_at RENAME TO idx_okapi_outbox_status_created_at; +``` + +### MySQL + +Rename the table in place, then remove the legacy indexes. The 1.0.0 changelog recreates +them under their new names. + +```sql +RENAME TABLE outbox TO okapi_outbox; +ALTER TABLE okapi_outbox + DROP INDEX idx_outbox_status_last_attempt, + DROP INDEX idx_outbox_status_created_at; +``` + +### Liquibase tracking tables + +By default, 1.0.0 creates `okapi_databasechangelog` and +`okapi_databasechangeloglock`. Let them start empty: the consolidated 1.0.0 changeset +will recognize the renamed table and record the current schema without deleting its +rows. + +To keep using the existing shared tracking tables instead, configure their names before +the first startup: + +```yaml +okapi: + liquibase: + changelog-table: databasechangelog + changelog-lock-table: databasechangeloglock +``` + +Do not copy the 0.2.x Liquibase rows into the new tracking table. Version 1.0.0 uses a +consolidated changeset with a different file name and checksum. diff --git a/docs/images/okapi-modules.png b/docs/images/okapi-modules.png new file mode 100644 index 0000000000000000000000000000000000000000..27a498d288a6345ee3c34c7c60be685ee89d5017 GIT binary patch literal 135862 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 Date: Wed, 12 Aug 2026 09:59:18 +0200 Subject: [PATCH 2/4] docs: tighten project introduction --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index a907ae7..74de0ee 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,7 @@ **Reliable message delivery for Kotlin and Java services, using the transactional outbox pattern.** -When your service saves something to the database and then has to notify another service, publish an event, or call a webhook, those two steps don't share a transaction. If you commit first, a crash or a network blip loses the notification. If you call the downstream inside the transaction, its latency and its failures become yours. - -okapi closes that gap: the message is written to an outbox table **inside your business transaction**, and a background processor delivers it afterwards, retrying on failure. +Okapi is a Kotlin/JVM library implementing the **transactional outbox pattern**. Messages are stored in the database within the same transaction as your business operation, then delivered asynchronously over HTTP or Kafka. This prevents messages from being lost between the database commit and the delivery attempt, without requiring distributed transactions. - **Storage**: PostgreSQL, MySQL 8+ - **Transports**: HTTP webhooks, Kafka From 3f75e4f1b94d11447b2741dfd39566f7b30d4060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Kobyli=C5=84ski?= Date: Wed, 12 Aug 2026 10:34:58 +0200 Subject: [PATCH 3/4] docs: restore README presentation details --- README.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 74de0ee..acd13dd 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# okapi +# Okapi [![Maven Central](https://img.shields.io/maven-central/v/com.softwaremill.okapi/okapi-core?label=maven%20central&color=blue)](https://central.sonatype.com/artifact/com.softwaremill.okapi/okapi-core) [![CI](https://github.com/softwaremill/okapi/workflows/CI/badge.svg)](https://github.com/softwaremill/okapi/actions?query=workflow%3A%22CI%22) @@ -261,7 +261,15 @@ For custom reactions to delivery events, implement `OutboxProcessorListener`. `O The runtime modules build on `okapi-core`; `okapi-bom` only aligns their versions. Pick a storage module, one or more transports, and a framework adapter if you want one. -[![Okapi module architecture](docs/images/okapi-modules.png)](https://softwaremill.com/transactional-outbox-with-okapi/) + + +

+ From Reliable Message Delivery: the Transactional Outbox Pattern With Okapi. +

| Module | Purpose | |---|---| @@ -284,6 +292,8 @@ The runtime modules build on `okapi-core`; `okapi-bom` only aligns their version | Kafka Clients | 3.9.x, 4.x | Included transitively by `okapi-kafka`; you can override the version in your build. | | Exposed | 1.x | `okapi-exposed` | +`okapi-spring-boot` does not bring Spring Boot transitively; your application controls the Spring Boot version. + The storage modules use plain JDBC. With Spring Boot, they participate in the transaction selected through a `PlatformTransactionManager`; `okapi-exposed` provides adapters for Exposed-managed transactions. ## Performance From 739dca051ee6284976e1fb6fcf81a7caec25737b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Kobyli=C5=84ski?= Date: Wed, 12 Aug 2026 12:01:25 +0200 Subject: [PATCH 4/4] docs: link example applications --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index acd13dd..ff0583e 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,10 @@ The order row and the outbox row now commit together or not at all. Autoconfigur > `SpringOutboxPublisher` throws `IllegalStateException` if you call `publish()` outside an active read-write transaction. That is deliberate — an outbox write that can't commit atomically with your business data defeats the purpose of the pattern. +## Examples + +Runnable, self-contained applications live in [okapi-examples](https://github.com/softwaremill/okapi-examples). Each one is an independent Gradle project that consumes okapi as a published dependency, with its own `docker-compose.yml` for the databases and brokers it needs. + ## How it works 1. `publish()` writes a `PENDING` row to `okapi_outbox` in your transaction.

+ + Okapi module architecture + +