Skip to main content

Getting started

This page shows how to add jEAP Messaging to a Spring Boot service and produce and consume a message over Kafka. For the bigger picture see Architecture; for an end-to-end checklist when wiring Kafka into a new service see the Kafka how-to.

1. Add the dependency

<dependency>
<groupId>ch.admin.bit.jeap</groupId>
<artifactId>jeap-messaging-infrastructure-kafka</artifactId>
</dependency>

The version is managed by the jEAP Spring Boot parent. This single artifact pulls in the Avro model and the Spring Boot auto-configuration. See Choosing dependencies for the other modules (schema registries, idempotence, test fixtures).

2. Add the message-type dependency

A service can only produce or consume message types for which a Java binding exists. Those bindings are generated from the Message Type Registry and consumed as normal Maven dependencies:

<dependency>
<groupId>ch.admin.bit.jme.messagetype.jme</groupId>
<artifactId>jme-declaration-created-event</artifactId>
<version>1.4.0</version>
</dependency>

3. Configure the cluster

The minimum configuration points the service at a Kafka cluster and a schema registry. All cluster properties live under jeap.messaging.kafka.* (see the full Configuration reference).

jeap:
messaging:
kafka:
cluster:
default-cluster:
bootstrapServers: localhost:9092
schemaRegistryUrl: http://localhost:8081
systemName: JME
serviceName: ${spring.application.name}
errorTopicName: jme-messageprocessing-failed

systemName and errorTopicName are required for the error handler to report failures; serviceName defaults to ${spring.application.name}.

4. Declare message contracts

Every produced and consumed message type needs a message contract, declared with an annotation anywhere in the service (typically on the @SpringBootApplication class):

@JeapMessageProducerContract(JmeDeclarationCreatedEvent.TypeRef.class)
@JeapMessageConsumerContract(JmeDeclarationCreatedEvent.TypeRef.class)
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

5. Publish a message

Build the message with its generated builder and send it with a KafkaTemplate. See Publishing messages for details and the MessagePublisher abstraction.

@Component
@RequiredArgsConstructor
class DeclarationPublisher {
private final KafkaTemplate<AvroMessageKey, AvroMessage> kafkaTemplate;

void publish(String declarationId) {
JmeDeclarationCreatedEvent event = JmeDeclarationCreatedEventBuilder.create()
.idempotenceId(declarationId)
.declarationIdReference(declarationId)
.build();
kafkaTemplate.send("jme-messaging-declaration-created", event);
}
}

6. Consume a message

A consumer is a Spring @KafkaListener. Always acknowledge after processing — see Consuming messages.

@Component
class DeclarationConsumer {
@KafkaListener(topics = "jme-messaging-declaration-created")
void consume(JmeDeclarationCreatedEvent event, Acknowledgment ack) {
// ... process the event ...
ack.acknowledge();
}
}

Because delivery is at-least-once, make consumers idempotent.