com.katanox.tabour.sqs.SqsRegistry.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of core Show documentation
Show all versions of core Show documentation
A Kotlin library to consume and produce SQS messages
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
}
}