Getting started
This page shows how to add the Sequential Inbox to a Spring Boot service that already uses jeap-messaging, declare a sequence, and process the released messages. For the bigger picture see How sequencing works.
1. Add the dependency
<dependency>
<groupId>ch.admin.bit.jeap</groupId>
<artifactId>jeap-messaging-sequential-inbox</artifactId>
</dependency>
The version is managed by the jEAP Spring Boot parent. Add jeap-messaging-sequential-inbox-rest-api
as well if you want the DevOps REST API.
2. Add the database schema
The library stores sequence instances and buffered messages in the database but does not create
the tables itself. Add the schema as a Flyway migration in your service. The canonical DDL lives in
the repository at
jeap-messaging-sequential-inbox-test/src/test/resources/db/migration/V1__create-sequential-inbox-schema.sql
and creates sequence_instance, sequenced_message, buffered_message, message_header and a
shedlock table.
If a shedlock table already exists (e.g. because @IdempotentMessageHandler is also used), do not
add it a second time.
3. Declare the sequences
Create src/main/resources/messaging/jeap-sequential-inbox.yml. Each sequence lists the message
types it sequences, how to extract the contextId, and the release condition (predecessors) for each
message. See the full Sequence declaration reference.
sequences:
- name: OrderSequence
retentionPeriod: 24h
messages:
- type: JmeOrderCreatedEvent
contextIdExtractor: ch.admin.bit.example.OrderIdExtractor
- type: JmeOrderShippedEvent
contextIdExtractor: ch.admin.bit.example.OrderIdExtractor
releaseCondition:
predecessor: JmeOrderCreatedEvent
The default location can be changed with jeap.messaging.sequential-inbox.config-location.
4. Implement a ContextIdExtractor
Each sequenced message type needs a ContextIdExtractor that returns the id grouping messages into
the same sequence instance (for example the order id). Returning null means the message cannot be
sequenced.
public class OrderIdExtractor implements ContextIdExtractor<AvroMessage> {
@Override
public String extractContextId(AvroMessage message) {
return message.getOptionalProcessId().orElse(null);
}
}
5. Handle released messages
Annotate handler methods with @SequentialInboxMessageListener. The library starts the Kafka
consumers and invokes your method only once a message is released by its release condition. The
method takes either the Avro message, or the key and the message.
@Component
class OrderListener {
@SequentialInboxMessageListener
void onOrderShipped(JmeOrderShippedEvent event) {
// ... processing in the declared order ...
}
@SequentialInboxMessageListener
void onOrderCreated(AvroMessageKey key, JmeOrderCreatedEvent event) {
// two-parameter variant when the key is needed
}
}
Do not add a @KafkaListener for sequenced topics yourself — the inbox owns the consumers and
buffers messages that are not yet releasable. Delivery is still at-least-once, so handlers must be
idempotent; the inbox additionally de-duplicates on the message idempotence id.