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

com.katanox.tabour.sqs.SqsRegistry.kt Maven / Gradle / Ivy

There is a newer version: 1.0
Show newest version
package com.katanox.tabour.sqs

import com.katanox.tabour.configuration.Registry
import com.katanox.tabour.consumption.Config
import com.katanox.tabour.error.ProducerNotFound
import com.katanox.tabour.sqs.config.SqsConsumer
import com.katanox.tabour.sqs.consumption.SqsPoller
import com.katanox.tabour.sqs.production.SqsDataProductionConfiguration
import com.katanox.tabour.sqs.production.SqsProducer
import com.katanox.tabour.sqs.production.SqsProducerExecutor
import java.net.URI
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider
import software.amazon.awssdk.regions.Region
import software.amazon.awssdk.services.sqs.SqsClient

/**
 * A type of [Registry] which works with SQS
 *
 * [T] is the key of the registry which is used to identify the registry
 *
 * Supports consumption and production of SQS messages
 */
class SqsRegistry
internal constructor(
    private val configuration: Configuration,
) : Registry {
    override val key: T
        get() = configuration.key

    private val consumers: MutableList> = mutableListOf()
    private val producers: MutableSet> = mutableSetOf()
    private val sqs: SqsClient =
        SqsClient.builder()
            .credentialsProvider(configuration.credentialsProvider)
            .region(configuration.region)
            .apply {
                if (configuration.endpointOverride != null) {
                    this.endpointOverride(configuration.endpointOverride)
                }
            }
            .build()

    private val sqsProducerExecutor = SqsProducerExecutor(sqs)
    private val sqsPoller = SqsPoller(sqs)

    /** Adds a consumer to the registry */
    fun addConsumer(consumer: SqsConsumer<*>): SqsRegistry =
        this.apply { consumers.add(consumer) }

    /** Adds a collection of consumers to the registry */
    fun addConsumers(consumers: List>): SqsRegistry =
        this.apply { consumers.fold(this) { registry, consumer -> registry.addConsumer(consumer) } }

    /** Adds a producer to the registry */
    fun  addProducer(producer: SqsProducer): SqsRegistry =
        this.apply { producers.add(producer) }

    /** Adds a collection of producers to the registry */
    fun  addProducers(producers: List>): SqsRegistry =
        this.apply { producers.fold(this) { registry, producer -> registry.addProducer(producer) } }

    /**
     * Starts the consuming process using the Consumers that have been registered up until the time
     * when start was used
     */
    override suspend fun startConsumption() {
        sqsPoller.poll(consumers)
    }

    override suspend fun stopConsumption() {
        sqsPoller.stopPolling()
    }

    suspend fun  produce(
        producerKey: T,
        productionConfiguration: SqsDataProductionConfiguration
    ) {
        val producer = producers.find { it.key == producerKey }

        if (producer != null) {
            sqsProducerExecutor.produce(producer, productionConfiguration)
        } else {
            productionConfiguration.resourceNotFound(ProducerNotFound(producerKey))
        }
    }

    class Configuration(
        /** Key of the registry */
        val key: T,
        /** Credentials to be used with the AWS SDK in order to perform AWS operations */
        val credentialsProvider: AwsCredentialsProvider,
        /** The region of the credentials */
        val region: Region,
    ) : Config {
        /**
         * Can be used to change the endpoint of the SQS queue. Usually this is for testing purposes
         * with Localstack
         */
        var endpointOverride: URI? = null
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy