Skip to content

Repository files navigation

nerv-event

nerv-event is a Spring Boot event-delivery library for applications that need durable, broker-neutral publication and consumption. It persists delivery intent before contacting Kafka or SQS, then uses a durable Inbox to make consumer processing recoverable and idempotency-aware.

Why nerv-event?

Publishing directly to a broker from a business transaction creates a failure window: the database can commit while the broker send fails, or the broker can receive an event while the database rolls back. nerv-event writes an Outbox record in the same transaction as the business update and sends it later. On the consumer side it persists an Inbox record before acknowledging the broker message.

Key capabilities include transactional Outbox publication, atomic database-local Inbox handling, optional aggregate ordering keys, Kafka and SQS adapters, database-backed retry, PostgreSQL migrations, observability, operations/manual recovery, retention, and multi-pod-safe claims with Outbox fencing tokens.

Installation

This source tree targets 2.1.0. Applications upgrading from 1.x must apply the new Outbox fencing migration and update any direct OutboxService integrations; see Upgrading to 2.0.

For normal Spring Boot applications, add the public starter:

<dependency>
  <groupId>com.czetsuyatech.nerv</groupId>
  <artifactId>nerv-event-spring-boot-starter</artifactId>
  <version>${nerv-event.version}</version>
</dependency>

The starter brings Spring integration, JPA persistence, and the Kafka and SQS adapters. Kafka and SQS are inactive until nerv.event.kafka.enabled=true and/or nerv.event.sqs.enabled=true. Outbox publication is auto-detected from an application RetryPolicy, custom OutboxDispatcher, configured destination, or nerv.event.outbox.enabled=true. Inbox-only applications need no Outbox setting. Once publication is active, startup fails if an OutboxService can accept publications but no functional dispatcher is available. nerv.event.outbox.enabled=false remains available as an explicit opt-out.

Quick Start

Configure PostgreSQL, apply the packaged migrations, select a broker, and map a logical destination:

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/orders
    username: orders
    password: ${ORDERS_DB_PASSWORD}
  jpa.hibernate.ddl-auto: validate

nerv:
  event:
    destinations:
      orders:
        broker: kafka
        target: order-events
    kafka:
      enabled: true

Inside a business transaction, build an EventMessage and publish an EventPublication to the logical destination. Implement EventHandler<T> for inbound event types. You do not need NERV component scanning, @EnableJpaRepositories, @EntityScan, @KafkaListener, or @SqsListener.

@Transactional
void createOrder(Order order) {
  orders.save(order);
  eventPublisher.publish(EventPublication.<OrderCreated>builder()
      .event(EventMessage.<OrderCreated>builder()
          .id(new EventId(UUID.randomUUID().toString()))
          .type("order.created")
          .timestamp(clock.instant())
          .source("orders")
          .payload(new OrderCreated(order.id()))
          .build())
      .destination(new Destination("orders"))
      .orderingKey(order.id().toString())
      .build());
}

The ordering key is optional. Same-key Outbox rows are dispatched in persisted sequence; Kafka uses it as the record key and SQS FIFO producers use it as the message group ID. Standard SQS queues provide no ordering guarantee. Polling jitter uses Java's standard java.base runtime and requires no optional random-provider module.

See Getting Started, Publishing, and Consuming for the complete path.

Architecture

Application -> EventPublisher -> Outbox -> OutboxDispatcher -> Kafka / SQS
Kafka / SQS -> consumer adapter -> Inbox -> ConsumerDispatcher -> EventHandlerInterceptor chain -> EventHandler<T>

The detailed module and lifecycle view is in Architecture.

Documentation

The runnable adoption reference is nerv-examples/nerv-event-spring-boot-demo.

Requirements and compatibility

  • Java 21 or newer
  • Spring Boot 4.1.0 dependency management (the current build baseline)
  • PostgreSQL is the tested production database; H2 is only a test/development convenience
  • Kafka and standard SQS queues are supported adapters

nerv-event provides at-least-once delivery, not distributed exactly-once processing. See Production guide before production adoption.

License and repository conventions

Use the project license and repository conventions in this repository. Maven coordinates use com.czetsuyatech.nerv; Java packages remain com.czetsuyatech.nerv.event.

About

nerv-event is a Spring Boot event-delivery library for applications that need durable, broker-neutral publication and consumption. It persists delivery intent before contacting Kafka or SQS, then uses a durable Inbox to make consumer processing recoverable and idempotency-aware.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages