public class Application implements ApplicationRunner
{
@Autowired
- EndlessConsumer endlessConsumer;
+ ApplicationRecordHandler recordHandler;
@Override
public void run(ApplicationArguments args) throws Exception
{
log.info("Starting EndlessConsumer");
- endlessConsumer.start();
+ recordHandler.start();
}
@PreDestroy
try
{
log.info("Stopping EndlessConsumer");
- endlessConsumer.stop();
+ recordHandler.stop();
}
catch (IllegalStateException e)
{
@Bean
public ApplicationRecordHandler applicationRecordHandler(
AdderResults adderResults,
+ KafkaListenerEndpointRegistry endpointRegistry,
+ ApplicationErrorHandler errorHandler,
KafkaProperties kafkaProperties,
ApplicationProperties applicationProperties)
{
return new ApplicationRecordHandler(
adderResults,
+ endpointRegistry,
+ errorHandler,
Optional.ofNullable(applicationProperties.getThrottle()),
kafkaProperties.getClientId());
}
{
return new ApplicationErrorHandler();
}
-
- @Bean
- public EndlessConsumer<String, Message> endlessConsumer(
- RecordHandler recordHandler,
- ApplicationErrorHandler errorHandler,
- KafkaProperties kafkaProperties,
- KafkaListenerEndpointRegistry endpointRegistry)
- {
- return
- new EndlessConsumer<>(
- kafkaProperties.getClientId(),
- endpointRegistry,
- errorHandler,
- recordHandler);
- }
}
@RequiredArgsConstructor
public class ApplicationHealthIndicator implements HealthIndicator
{
- private final EndlessConsumer<String, Message> consumer;
+ private final ApplicationRecordHandler consumer;
@Override
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.ConsumerRecord;
+import org.springframework.kafka.config.KafkaListenerEndpointRegistry;
import java.time.Duration;
import java.util.HashMap;
public class ApplicationRecordHandler implements RecordHandler<String, Message>
{
private final AdderResults results;
+ private final KafkaListenerEndpointRegistry registry;
+ private final ApplicationErrorHandler errorHandler;
private final Optional<Duration> throttle;
private final String id;
{
return state.get(partition);
}
+
+
+
+ public void start()
+ {
+ if (running())
+ throw new IllegalStateException("Consumer instance " + id + " is already running!");
+
+ log.info("{} - Starting", id);
+ errorHandler.clearState();
+ registry.getListenerContainer(id).start();
+ }
+
+ public void stop()
+ {
+ if (running())
+ throw new IllegalStateException("Consumer instance " + id + " is not running!");
+
+ log.info("{} - Stopping", id);
+ registry.getListenerContainer(id).stop();
+ log.info("{} - Stopped", id);
+ }
+
+ public boolean running()
+ {
+ return registry.getListenerContainer(id).isRunning();
+ }
+
+ public Optional<Exception> exitStatus()
+ {
+ if (running())
+ throw new IllegalStateException("No exit-status available: Consumer instance " + id + " is running!");
+
+ return errorHandler.getException();
+ }
}
@RequiredArgsConstructor
public class DriverController
{
- private final EndlessConsumer consumer;
private final ApplicationRecordHandler recordHandler;
private final AdderResults results;
@PostMapping("start")
public void start()
{
- consumer.start();
+ recordHandler.start();
}
@PostMapping("stop")
public void stop() throws ExecutionException, InterruptedException
{
- consumer.stop();
+ recordHandler.stop();
}
+++ /dev/null
-package de.juplo.kafka;
-
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.kafka.clients.consumer.ConsumerRecord;
-import org.springframework.kafka.annotation.KafkaListener;
-import org.springframework.kafka.config.KafkaListenerEndpointRegistry;
-
-import java.util.List;
-import java.util.Optional;
-
-
-@RequiredArgsConstructor
-@Slf4j
-public class EndlessConsumer<K, V>
-{
- private final String id;
- private final KafkaListenerEndpointRegistry registry;
- private final ApplicationErrorHandler errorHandler;
- private final RecordHandler<K, V> recordHandler;
-
- private long consumed = 0;
-
-
- @KafkaListener(
- id = "${spring.kafka.client-id}",
- idIsGroup = false,
- topics = "${sumup.adder.topic}",
- batch = "true",
- autoStartup = "false")
- public void accept(List<ConsumerRecord<K, V>> records)
- {
- // Do something with the data...
- log.info("{} - Received {} messages", id, records.size());
- for (ConsumerRecord<K, V> record : records)
- {
- log.info(
- "{} - {}: {}/{} - {}={}",
- id,
- record.offset(),
- record.topic(),
- record.partition(),
- record.key(),
- record.value()
- );
-
- recordHandler.accept(record);
-
- consumed++;
- }
- }
-
- public void start()
- {
- if (running())
- throw new IllegalStateException("Consumer instance " + id + " is already running!");
-
- log.info("{} - Starting - consumed {} messages before", id, consumed);
- errorHandler.clearState();
- registry.getListenerContainer(id).start();
- }
-
- public void stop()
- {
- if (running())
- throw new IllegalStateException("Consumer instance " + id + " is not running!");
-
- log.info("{} - Stopping", id);
- registry.getListenerContainer(id).stop();
- log.info("{} - Stopped - consumed {} messages so far", id, consumed);
- }
-
- public boolean running()
- {
- return registry.getListenerContainer(id).isRunning();
- }
-
- public Optional<Exception> exitStatus()
- {
- if (running())
- throw new IllegalStateException("No exit-status available: Consumer instance " + id + " is running!");
-
- return errorHandler.getException();
- }
-}