package it.tdlight.reactiveapi; import it.tdlight.reactiveapi.Event.ClientBoundEvent; import java.time.Duration; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import org.apache.kafka.clients.producer.ProducerConfig; import org.apache.kafka.clients.producer.ProducerRecord; import org.apache.kafka.common.serialization.IntegerSerializer; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.core.publisher.SignalType; import reactor.kafka.sender.KafkaSender; import reactor.kafka.sender.SenderOptions; import reactor.kafka.sender.SenderRecord; public class KafkaProducer { private static final Logger LOG = LogManager.getLogger(KafkaProducer.class); private final KafkaSender sender; public KafkaProducer(KafkaParameters kafkaParameters) { Map props = new HashMap<>(); props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaParameters.bootstrapServers()); props.put(ProducerConfig.CLIENT_ID_CONFIG, kafkaParameters.clientId()); props.put(ProducerConfig.ACKS_CONFIG, "all"); props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, IntegerSerializer.class); props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, ClientBoundEventSerializer.class); SenderOptions senderOptions = SenderOptions.create(props); sender = KafkaSender.create(senderOptions.maxInFlight(1024)); } public Mono sendMessages(UserTopic userId, Flux eventsFlux) { return eventsFlux .>map(event -> SenderRecord.create(new ProducerRecord<>( userId.getTopic(), event ), null)) .log("produce-messages-" + userId, Level.FINEST, SignalType.REQUEST, SignalType.ON_NEXT, SignalType.ON_ERROR, SignalType.ON_COMPLETE ) .transform(sender::send) .doOnError(e -> LOG.error("Send failed", e)) .then(); } public void close() { sender.close(); } }