
entry-point.sqs-reactive.sqs-listener.mustache Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scaffold-clean-architecture Show documentation
Show all versions of scaffold-clean-architecture Show documentation
Gradle plugin to create a clean application in Java that already works, It follows our best practices!
package {{package}}.sqs.listener.helper;
import {{package}}.sqs.listener.config.SQSProperties;
{{#lombok}}
import lombok.Builder;
import lombok.extern.log4j.Log4j2;
{{/lombok}}
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import software.amazon.awssdk.services.sqs.SqsAsyncClient;
import software.amazon.awssdk.services.sqs.model.DeleteMessageRequest;
import software.amazon.awssdk.services.sqs.model.Message;
import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Function;
{{#lombok}}
@Log4j2
@Builder
{{/lombok}}
public class SQSListener {
{{^lombok}}
private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(SQSListener.class);
{{/lombok}}
private final SqsAsyncClient client;
private final SQSProperties properties;
private final Function> processor;
{{#metrics}}
private String operation;
{{/metrics}}
{{^lombok}}
public SQSListener(final SqsAsyncClient client, final SQSProperties properties, final Function> processor) {
this.client = client;
this.properties = properties;
this.processor = processor;
}
{{/lombok}}
public SQSListener start() {
{{#metrics}}
this.operation = "MessageFrom:" + properties.getQueueUrl();
{{/metrics}}
ExecutorService service = Executors.newFixedThreadPool(properties.getNumberOfThreads());
Flux flow = listenRetryRepeat().publishOn(Schedulers.fromExecutorService(service));
for (var i = 0; i < properties.getNumberOfThreads(); i++) {
flow.subscribe();
}
return this;
}
private Flux listenRetryRepeat() {
return listen()
.doOnError(e -> log.error("Error listening sqs queue", e))
.repeat();
}
private Flux listen() {
return getMessages()
.flatMap(message -> processor.apply(message)
{{#metrics}}
.name("async_operation")
.tag("operation", operation)
.metrics()
{{/metrics}}
.then(confirm(message)))
.onErrorContinue((e, o) -> log.error("Error listening sqs message", e));
}
private Mono confirm(Message message) {
return Mono.fromCallable(() -> getDeleteMessageRequest(message.receiptHandle()))
.flatMap(request -> Mono.fromFuture(client.deleteMessage(request)))
.then();
}
private Flux getMessages() {
return Mono.fromCallable(this::getReceiveMessageRequest)
.flatMap(request -> Mono.fromFuture(client.receiveMessage(request)))
.doOnNext(response -> log.debug("{} received messages from sqs", response.messages().size()))
.flatMapMany(response -> Flux.fromIterable(response.messages()));
}
private ReceiveMessageRequest getReceiveMessageRequest() {
return ReceiveMessageRequest.builder()
.queueUrl(properties.getQueueUrl())
.maxNumberOfMessages(properties.getMaxNumberOfMessages())
.waitTimeSeconds(properties.getWaitTimeSeconds())
.visibilityTimeout(properties.getVisibilityTimeoutSeconds())
.build();
}
private DeleteMessageRequest getDeleteMessageRequest(String receiptHandle) {
return DeleteMessageRequest.builder()
.queueUrl(properties.getQueueUrl())
.receiptHandle(receiptHandle)
.build();
}
{{^lombok}}
public static class SQSListenerBuilder {
private SqsAsyncClient client;
private SQSProperties properties;
private Function> processor;
SQSListenerBuilder() {
}
public SQSListener.SQSListenerBuilder client(final SqsAsyncClient client) {
this.client = client;
return this;
}
public SQSListener.SQSListenerBuilder properties(final SQSProperties properties) {
this.properties = properties;
return this;
}
public SQSListener.SQSListenerBuilder processor(final Function> processor) {
this.processor = processor;
return this;
}
public SQSListener build() {
return new SQSListener(this.client, this.properties, this.processor);
}
}
public static SQSListener.SQSListenerBuilder builder() {
return new SQSListener.SQSListenerBuilder();
}
{{/lombok}}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy