Skip to content
Snippets Groups Projects
Commit c3acad6c authored by Benedikt Wetzel's avatar Benedikt Wetzel
Browse files

minor code changes/enhancements

parent 9808367c
No related branches found
No related tags found
1 merge request!168Enhance Code Quality
......@@ -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.
*/
......
......@@ -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,
......
......@@ -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())
}
......
......@@ -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" }
}
......
......@@ -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("")
......
......@@ -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.
......
......@@ -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
}
......@@ -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()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment