run.qontract.core.pattern.KafkaMessagePattern.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of qontract-core Show documentation
Show all versions of qontract-core Show documentation
A Contract Testing Tool that leverages Gherkin to describe APIs in a human readable and machine enforceable manner
package run.qontract.core.pattern
import run.qontract.core.Resolver
import run.qontract.core.Result
import run.qontract.core.breadCrumb
import run.qontract.core.value.EmptyString
import run.qontract.core.value.KafkaMessage
import run.qontract.core.value.StringValue
const val KAFKA_MESSAGE_BREADCRUMB = "KAFKA-MESSAGE"
data class KafkaMessagePattern(val topic: String = "", val key: Pattern = EmptyStringPattern, val value: Pattern = StringPattern) {
fun matches(message: KafkaMessage, resolver: Resolver): Result = attempt(KAFKA_MESSAGE_BREADCRUMB) {
try {
matchTopics(message).ifSuccess {
matchKey(message, resolver)
}.ifSuccess {
matchValue(message, resolver)
}
} catch (e: ContractException) {
e.failure()
}.breadCrumb(KAFKA_MESSAGE_BREADCRUMB)
}
private fun matchValue(message: KafkaMessage, resolver: Resolver): Result = try {
val parsedValue = when (message.value) {
is StringValue -> value.parse(message.value.string, resolver)
else -> message.value
}
value.matches(parsedValue, resolver)
} catch (e: ContractException) {
e.failure()
}.breadCrumb("VALUE")
private fun matchKey(message: KafkaMessage, resolver: Resolver): Result = try {
val parsedKey = when (message.key) {
is StringValue -> key.parse(message.key.string, resolver)
else -> message.key
}
key.matches(parsedKey ?: EmptyString, resolver)
} catch (e: ContractException) {
e.failure()
}.breadCrumb("KEY")
private fun matchTopics(message: KafkaMessage): Result = when (message.topic) {
topic -> Result.Success()
else -> Result.Failure("Expected topic $topic, got $message.topic").breadCrumb("TOPIC")
}
fun encompasses(other: KafkaMessagePattern, thisResolver: Resolver, otherResolver: Resolver): Result =
attempt(KAFKA_MESSAGE_BREADCRUMB) {
topicsShouldMatch(other).ifSuccess {
key.encompasses(other.key, otherResolver, thisResolver).breadCrumb("KEY")
}.ifSuccess {
value.encompasses(other.value, thisResolver, otherResolver).breadCrumb("VALUE")
}.breadCrumb(KAFKA_MESSAGE_BREADCRUMB)
}
private fun topicsShouldMatch(other: KafkaMessagePattern): Result = when (topic) {
other.topic -> Result.Success()
else -> Result.Failure("Expected topic $topic, got ${other.topic}").breadCrumb("TOPIC")
}
fun newBasedOn(row: Row, resolver: Resolver): List {
val newKeys = key.newBasedOn(row, resolver)
val newValues = value.newBasedOn(row, resolver)
return newKeys.flatMap { newKey ->
newValues.map { newValue ->
KafkaMessagePattern(topic, newKey, newValue)
}
}
}
fun generate(resolver: Resolver): KafkaMessage =
KafkaMessage(topic, key.generate(resolver) as StringValue, value.generate(resolver) as StringValue)
}