All Downloads are FREE. Search and download functionalities are using the official Maven repository.

entry-point.sqs-reactive.sqs-listener.mustache Maven / Gradle / Ivy

Go to download

Gradle plugin to create a clean application in Java that already works, It follows our best practices!

There is a newer version: 3.20.10
Show newest version
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