diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/BenchmarkExecution.kt b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/BenchmarkExecution.kt index 62ab75898d16ff2732ab6aa5c254ec8f87fb7266..63b554e6a023d9b39b16c8a130b7fbf00926acdd 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/BenchmarkExecution.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/BenchmarkExecution.kt @@ -18,7 +18,7 @@ import kotlin.properties.Delegates * - An [execution] that encapsulates: the strategy, the duration, and the restrictions * for the execution of the benchmark. * - [configOverrides] additional configurations. - * This class is used for parsing(in [theodolite.execution.TheodoliteYamlExecutor]) and + * This class is used for parsing(in [theodolite.execution.TheodoliteStandalone]) and * for the deserializing in the [theodolite.execution.operator.TheodoliteOperator]. * @constructor construct an empty BenchmarkExecution. */ diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt index aa9c36ad912437e3b104dccf6ff1f4dea5905946..753fd0805fcfa3fbf7fe5c26e8591e881195323a 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt @@ -2,8 +2,6 @@ package theodolite.benchmark import com.fasterxml.jackson.databind.annotation.JsonDeserialize import io.fabric8.kubernetes.api.model.KubernetesResource -import io.fabric8.kubernetes.api.model.Namespaced -import io.fabric8.kubernetes.client.CustomResource import io.fabric8.kubernetes.client.DefaultKubernetesClient import io.quarkus.runtime.annotations.RegisterForReflection import mu.KotlinLogging @@ -14,6 +12,7 @@ import theodolite.util.* private val logger = KotlinLogging.logger {} private var DEFAULT_NAMESPACE = "default" +private var DEFAULT_THEODOLITE_APP_RESOURCES = "./config" /** * Represents a benchmark in Kubernetes. An example for this is the BenchmarkType.yaml @@ -27,7 +26,7 @@ private var DEFAULT_NAMESPACE = "default" * - [namespace] for the client, * - [path] under which the resource yamls can be found. * - * This class is used for the parsing(in the [theodolite.execution.TheodoliteYamlExecutor]) and + * This class is used for the parsing(in the [theodolite.execution.TheodoliteStandalone]) and * for the deserializing in the [theodolite.execution.operator.TheodoliteOperator]. * @constructor construct an empty Benchmark. */ @@ -41,7 +40,6 @@ class KubernetesBenchmark: KubernetesResource, Benchmark{ lateinit var loadTypes: List<TypeName> lateinit var kafkaConfig: KafkaConfig var namespace = System.getenv("NAMESPACE") ?: DEFAULT_NAMESPACE - var path = System.getenv("THEODOLITE_APP_RESOURCES") ?: "./config" /** @@ -50,8 +48,11 @@ class KubernetesBenchmark: KubernetesResource, Benchmark{ * the [K8sResourceLoader] */ private fun loadKubernetesResources(resources: List<String>): List<Pair<String, KubernetesResource>> { + val path = System.getenv("THEODOLITE_APP_RESOURCES") ?: DEFAULT_THEODOLITE_APP_RESOURCES + logger.info { "Using $path as resource path." } + val parser = YamlParser() - val loader = K8sResourceLoader(DefaultKubernetesClient().inNamespace(namespace)) + val loader = K8sResourceLoader(DefaultKubernetesClient()) return resources .map { resource -> val resourcePath = "$path/$resource" @@ -78,7 +79,6 @@ class KubernetesBenchmark: KubernetesResource, Benchmark{ afterTeardownDelay: Long ): BenchmarkDeployment { logger.info { "Using $namespace as namespace." } - logger.info { "Using $path as resource path." } val appResources = loadKubernetesResources(this.appResource) val loadGenResources = loadKubernetesResources(this.loadGenResource) @@ -100,7 +100,6 @@ class KubernetesBenchmark: KubernetesResource, Benchmark{ } } return KubernetesBenchmarkDeployment( - namespace = namespace, appResources = appResources.map { it.second }, loadGenResources = loadGenResources.map { it.second }, loadGenerationDelay = loadGenerationDelay, diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkDeployment.kt b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkDeployment.kt index 6cf239676ddb24752f4754a85fc62657f9eb6603..d5a4df074fd220dc8b62d5ecc8430b298735e0cf 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkDeployment.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkDeployment.kt @@ -22,7 +22,6 @@ private val logger = KotlinLogging.logger {} */ @RegisterForReflection class KubernetesBenchmarkDeployment( - val namespace: String, val appResources: List<KubernetesResource>, val loadGenResources: List<KubernetesResource>, private val loadGenerationDelay: Long, @@ -60,7 +59,7 @@ class KubernetesBenchmarkDeployment( loadGenResources.forEach { kubernetesManager.remove(it) } appResources.forEach { kubernetesManager.remove(it) } kafkaController.removeTopics(this.topics.map { topic -> topic.name }) - KafkaLagExporterRemover(client).remove(LAG_EXPORTER_POD_LABEL) + ResourceByLabelRemover(client).removePod(LAG_EXPORTER_POD_LABEL) logger.info { "Teardown complete. Wait $afterTeardownDelay ms to let everything come down." } Thread.sleep(Duration.ofSeconds(afterTeardownDelay).toMillis()) } diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KafkaLagExporterRemover.kt b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/ResourceByLabelRemover.kt similarity index 64% rename from theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KafkaLagExporterRemover.kt rename to theodolite-quarkus/src/main/kotlin/theodolite/benchmark/ResourceByLabelRemover.kt index e8179b42d40e40e7ed45a8f5c48fe26f235be334..db242b6a7e170d1eb93225e6c019d0ae1f71d281 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KafkaLagExporterRemover.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/ResourceByLabelRemover.kt @@ -9,13 +9,15 @@ private val logger = KotlinLogging.logger {} * Used to reset the KafkaLagExporter by deleting the pod. * @param client NamespacedKubernetesClient used for the deletion. */ -class KafkaLagExporterRemover(private val client: NamespacedKubernetesClient) { +// TODO(Maybe we can add support to delete arbitrary resources (kinds), +// then we can use this class also inside the ClusterSetup class instead of the clearByLabel function.) +class ResourceByLabelRemover(private val client: NamespacedKubernetesClient) { /** * Deletes all pods with the selected label. * @param [label] of the pod that should be deleted. */ - fun remove(label: String) { + fun removePod(label: String) { this.client.pods().withLabel(label).delete() logger.info { "Pod with label: $label deleted" } } diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt b/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt index ef4d371173c7099eb091f90cddbe26d31e6522be..050094b88d5ddc803d831da9030fb81109859246 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt @@ -12,6 +12,7 @@ import java.util.* import java.util.regex.Pattern private val logger = KotlinLogging.logger {} +private val RECORD_LAG_QUERY = "sum by(group)(kafka_consumergroup_group_lag >= 0)" /** * Contains the analysis. Fetches a metric from Prometheus, documents it, and evaluates it. @@ -32,7 +33,7 @@ class AnalysisExecutor( * First fetches data from prometheus, then documents them and afterwards evaluate it via a [slo]. * @param load of the experiment. * @param res of the experiment. - * @param executionDuration of the experiment. + * @param executionIntervals list of start and end points of experiments * @return true if the experiment succeeded. */ fun analyze(load: LoadDimension, res: Resource, executionIntervals: List<Pair<Instant, Instant>>): Boolean { @@ -48,7 +49,7 @@ class AnalysisExecutor( .map { interval -> fetcher.fetchMetric( start = interval.first, end = interval.second, - query = "sum by(group)(kafka_consumergroup_group_lag >= 0)") } + query = RECORD_LAG_QUERY) } prometheusData.forEach{ data -> ioHandler.writeToCSVFile( @@ -67,6 +68,7 @@ class AnalysisExecutor( result = sloChecker.evaluate(prometheusData) } catch (e: Exception) { + // TODO(throw exception in order to make it possible to mark an experiment as unsuccessfully) logger.error { "Evaluation failed for resource '${res.get()}' and load '${load.get()}'. Error: $e" } } return result @@ -75,7 +77,7 @@ class AnalysisExecutor( private val NONLATIN: Pattern = Pattern.compile("[^\\w-]") private val WHITESPACE: Pattern = Pattern.compile("[\\s]") - fun String.toSlug(): String { + private fun String.toSlug(): String { val noWhitespace: String = WHITESPACE.matcher(this).replaceAll("-") val normalized: String = Normalizer.normalize(noWhitespace, Normalizer.Form.NFD) val slug: String = NONLATIN.matcher(normalized).replaceAll("") diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/ExternalSloChecker.kt b/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/ExternalSloChecker.kt index f7ebee8faf740583dbe6a37381a599e9bde19280..797798eff38699350e45f481f599644e7c01f2d1 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/ExternalSloChecker.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/ExternalSloChecker.kt @@ -5,7 +5,6 @@ import khttp.post import mu.KotlinLogging import theodolite.util.PrometheusResponse import java.net.ConnectException -import java.time.Instant /** * [SloChecker] that uses an external source for the concrete evaluation. diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/SloChecker.kt b/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/SloChecker.kt index 9ee5fe7ef34ce5b6214882ce2c1d19677f1d7130..af70fa5dca3f0556d38791ed96c2af30b9a44a68 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/SloChecker.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/SloChecker.kt @@ -8,13 +8,10 @@ import theodolite.util.PrometheusResponse */ interface SloChecker { /** - * Evaluates [fetchedData] and returns if the experiment was successful. - * Returns if the evaluated experiment was successful. + * Evaluates [fetchedData] and returns if the experiments were successful. * - * @param start of the experiment - * @param end of the experiment * @param fetchedData from Prometheus that will be evaluated. - * @return true if experiment was successful. Otherwise false. + * @return true if experiments were successful. Otherwise false. */ fun evaluate(fetchedData: List<PrometheusResponse>): Boolean } diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteYamlExecutor.kt b/theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteStandalone.kt similarity index 97% rename from theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteYamlExecutor.kt rename to theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteStandalone.kt index b9977029703c8012ada7fb3d7766bfa321a836c3..847d9c30666283df6233d3d791a6dca9b81eeb7a 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteYamlExecutor.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteStandalone.kt @@ -25,6 +25,7 @@ private val logger = KotlinLogging.logger {} * * @constructor Create empty Theodolite yaml executor */ +// TODO(rename class to standaloneMode or similar) class TheodoliteYamlExecutor { private val parser = YamlParser()