Skip to content
Snippets Groups Projects
Commit e736e5cf authored by Lorenz Boguhn's avatar Lorenz Boguhn
Browse files

Refactoring using detekt suggestions

parent 0ab463f9
No related branches found
No related tags found
4 merge requests!159Re-implementation of Theodolite with Kotlin/Quarkus,!157Update Graal Image in CI pipeline,!85Introduce new Benchmark class and Patcher,!83WIP: Re-implementation of Theodolite with Kotlin/Quarkus
Showing
with 143 additions and 80 deletions
package theodolite.benchmark package theodolite.benchmark
import theodolite.util.LoadDimension
import theodolite.util.ConfigurationOverride import theodolite.util.ConfigurationOverride
import theodolite.util.LoadDimension
import theodolite.util.Resource import theodolite.util.Resource
interface Benchmark { interface Benchmark {
fun buildDeployment(load: LoadDimension, res: Resource, configurationOverrides: List<ConfigurationOverride>): BenchmarkDeployment fun buildDeployment(
load: LoadDimension,
res: Resource,
configurationOverrides: List<ConfigurationOverride>
): BenchmarkDeployment
} }
...@@ -3,7 +3,6 @@ package theodolite.benchmark ...@@ -3,7 +3,6 @@ package theodolite.benchmark
import theodolite.util.ConfigurationOverride import theodolite.util.ConfigurationOverride
import kotlin.properties.Delegates import kotlin.properties.Delegates
class BenchmarkExecution { class BenchmarkExecution {
lateinit var name: String lateinit var name: String
lateinit var benchmark: String lateinit var benchmark: String
......
...@@ -9,14 +9,12 @@ import java.util.* ...@@ -9,14 +9,12 @@ import java.util.*
class KubernetesBenchmark : Benchmark { class KubernetesBenchmark : Benchmark {
lateinit var name: String lateinit var name: String
private lateinit var appResource: List<String> lateinit var appResource: List<String>
private lateinit var loadGenResource: List<String> lateinit var loadGenResource: List<String>
private lateinit var resourceTypes: List<TypeName> lateinit var resourceTypes: List<TypeName>
private lateinit var loadTypes: List<TypeName> lateinit var loadTypes: List<TypeName>
private lateinit var kafkaConfig: KafkaConfig lateinit var kafkaConfig: KafkaConfig
private lateinit var zookeeperConfig: HashMap<String,String> lateinit var zookeeperConfig: HashMap<String, String>
private fun loadKubernetesResources(resources: List<String>): List<Pair<String, KubernetesResource>> { private fun loadKubernetesResources(resources: List<String>): List<Pair<String, KubernetesResource>> {
val basePath = "./../../../resources/main/yaml/" val basePath = "./../../../resources/main/yaml/"
...@@ -31,7 +29,11 @@ class KubernetesBenchmark: Benchmark { ...@@ -31,7 +29,11 @@ class KubernetesBenchmark: Benchmark {
} }
} }
override fun buildDeployment(load: LoadDimension, res: Resource, configurationOverrides: List<ConfigurationOverride>): BenchmarkDeployment { override fun buildDeployment(
load: LoadDimension,
res: Resource,
configurationOverrides: List<ConfigurationOverride>
): BenchmarkDeployment {
val resources = loadKubernetesResources(this.appResource + this.loadGenResource) val resources = loadKubernetesResources(this.appResource + this.loadGenResource)
val patcherManager = PatcherManager() val patcherManager = PatcherManager()
...@@ -40,13 +42,19 @@ class KubernetesBenchmark: Benchmark { ...@@ -40,13 +42,19 @@ class KubernetesBenchmark: Benchmark {
patcherManager.createAndApplyPatcher(load.getType(), this.loadTypes, resources, load.get().toString()) patcherManager.createAndApplyPatcher(load.getType(), this.loadTypes, resources, load.get().toString())
// patch overrides // patch overrides
configurationOverrides.forEach{ override -> patcherManager.applyPatcher(listOf(override.patcher), resources, override.value)} configurationOverrides.forEach { override ->
patcherManager.applyPatcher(
listOf(override.patcher),
resources,
override.value
)
}
return KubernetesBenchmarkDeployment( return KubernetesBenchmarkDeployment(
resources = resources.map { r -> r.second }, resources = resources.map { r -> r.second },
kafkaConfig = hashMapOf("bootstrap.servers" to kafkaConfig.bootstrapServer), kafkaConfig = hashMapOf("bootstrap.servers" to kafkaConfig.bootstrapServer),
zookeeperConfig = zookeeperConfig["server"].toString(), zookeeperConfig = zookeeperConfig["server"].toString(),
topics = kafkaConfig.getKafkaTopics()) topics = kafkaConfig.getKafkaTopics()
)
} }
} }
...@@ -32,6 +32,5 @@ class KubernetesBenchmarkDeployment( ...@@ -32,6 +32,5 @@ class KubernetesBenchmarkDeployment(
resources.forEach { resources.forEach {
kubernetesManager.remove(it) kubernetesManager.remove(it)
} }
} }
} }
package theodolite.evaluation package theodolite.evaluation
interface SLOChecker { interface SLOChecker {}
}
\ No newline at end of file
...@@ -2,7 +2,10 @@ package theodolite.execution ...@@ -2,7 +2,10 @@ package theodolite.execution
import mu.KotlinLogging import mu.KotlinLogging
import theodolite.benchmark.Benchmark import theodolite.benchmark.Benchmark
import theodolite.util.* import theodolite.util.ConfigurationOverride
import theodolite.util.LoadDimension
import theodolite.util.Resource
import theodolite.util.Results
import java.time.Duration import java.time.Duration
private val logger = KotlinLogging.logger {} private val logger = KotlinLogging.logger {}
...@@ -15,7 +18,12 @@ private val logger = KotlinLogging.logger {} ...@@ -15,7 +18,12 @@ private val logger = KotlinLogging.logger {}
* @property executionDuration * @property executionDuration
* @constructor Create empty Benchmark executor * @constructor Create empty Benchmark executor
*/ */
abstract class BenchmarkExecutor(val benchmark: Benchmark, val results: Results, val executionDuration: Duration, configurationOverrides: List<ConfigurationOverride>) { abstract class BenchmarkExecutor(
val benchmark: Benchmark,
val results: Results,
val executionDuration: Duration,
configurationOverrides: List<ConfigurationOverride>
) {
/** /**
* Run a experiment for the given parametrization, evaluate the experiment and save the result. * Run a experiment for the given parametrization, evaluate the experiment and save the result.
......
package theodolite.execution package theodolite.execution
import theodolite.benchmark.Benchmark import theodolite.benchmark.Benchmark
import theodolite.util.* import theodolite.util.ConfigurationOverride
import theodolite.util.LoadDimension
import theodolite.util.Resource
import theodolite.util.Results
import java.time.Duration import java.time.Duration
class BenchmarkExecutorImpl(benchmark: Benchmark, results: Results, executionDuration: Duration, private val configurationOverrides: List<ConfigurationOverride>) : BenchmarkExecutor(benchmark, results, executionDuration, configurationOverrides) { class BenchmarkExecutorImpl(
benchmark: Benchmark,
results: Results,
executionDuration: Duration,
private val configurationOverrides: List<ConfigurationOverride>
) : BenchmarkExecutor(benchmark, results, executionDuration, configurationOverrides) {
override fun runExperiment(load: LoadDimension, res: Resource): Boolean { override fun runExperiment(load: LoadDimension, res: Resource): Boolean {
val benchmarkDeployment = benchmark.buildDeployment(load, res, this.configurationOverrides) val benchmarkDeployment = benchmark.buildDeployment(load, res, this.configurationOverrides)
benchmarkDeployment.setup() benchmarkDeployment.setup()
......
...@@ -12,7 +12,8 @@ import java.time.Duration ...@@ -12,7 +12,8 @@ import java.time.Duration
class TheodoliteExecutor( class TheodoliteExecutor(
private val config: BenchmarkExecution, private val config: BenchmarkExecution,
private val kubernetesBenchmark: KubernetesBenchmark) { private val kubernetesBenchmark: KubernetesBenchmark
) {
private fun buildConfig(): Config { private fun buildConfig(): Config {
val results = Results() val results = Results()
...@@ -23,11 +24,17 @@ class TheodoliteExecutor( ...@@ -23,11 +24,17 @@ class TheodoliteExecutor(
return Config( return Config(
loads = config.load.loadValues.map { load -> LoadDimension(load, config.load.loadType) }, loads = config.load.loadValues.map { load -> LoadDimension(load, config.load.loadType) },
resources = config.resources.resourceValues.map { resource -> Resource(resource, config.resources.resourceType) }, resources = config.resources.resourceValues.map
{ resource -> Resource(resource, config.resources.resourceType) },
compositeStrategy = CompositeStrategy( compositeStrategy = CompositeStrategy(
benchmarkExecutor = executor, benchmarkExecutor = executor,
searchStrategy = strategyFactory.createSearchStrategy(executor, config.execution.strategy), searchStrategy = strategyFactory.createSearchStrategy(executor, config.execution.strategy),
restrictionStrategies = strategyFactory.createRestrictionStrategy(results, config.execution.restrictions))) restrictionStrategies = strategyFactory.createRestrictionStrategy(
results,
config.execution.restrictions
)
)
)
} }
fun run() { fun run() {
......
package theodolite.execution package theodolite.execution
import theodolite.benchmark.BenchmarkExecution import theodolite.benchmark.BenchmarkExecution
import theodolite.util.YamlParser
import theodolite.benchmark.KubernetesBenchmark import theodolite.benchmark.KubernetesBenchmark
import theodolite.util.YamlParser
class TheodoliteYamlExecutor { class TheodoliteYamlExecutor {
fun run() { fun run() {
// load the BenchmarkExecution and the BenchmarkType // load the BenchmarkExecution and the BenchmarkType
val parser = YamlParser() val parser = YamlParser()
val benchmarkExecution = parser.parse("./../../../resources/main/yaml/testBenchmarkExecution.yaml", BenchmarkExecution::class.java) !! val benchmarkExecution =
val benchmark = parser.parse("./../../../resources/main/yaml/testBenchmarkType.yaml", KubernetesBenchmark::class.java) !! parser.parse("./../../../resources/main/yaml/testBenchmarkExecution.yaml", BenchmarkExecution::class.java)!!
val benchmark =
parser.parse("./../../../resources/main/yaml/testBenchmarkType.yaml", KubernetesBenchmark::class.java)!!
val executor = TheodoliteExecutor(benchmarkExecution, benchmark) val executor = TheodoliteExecutor(benchmarkExecution, benchmark)
executor.run() executor.run()
......
...@@ -6,7 +6,6 @@ import io.fabric8.kubernetes.api.model.Service ...@@ -6,7 +6,6 @@ import io.fabric8.kubernetes.api.model.Service
import io.fabric8.kubernetes.api.model.apps.Deployment import io.fabric8.kubernetes.api.model.apps.Deployment
import io.fabric8.kubernetes.api.model.apps.StatefulSet import io.fabric8.kubernetes.api.model.apps.StatefulSet
import io.fabric8.kubernetes.client.NamespacedKubernetesClient import io.fabric8.kubernetes.client.NamespacedKubernetesClient
import java.lang.IllegalArgumentException
class K8sManager(private val client: NamespacedKubernetesClient) { class K8sManager(private val client: NamespacedKubernetesClient) {
fun deploy(resource: KubernetesResource) { fun deploy(resource: KubernetesResource) {
......
...@@ -4,7 +4,6 @@ import mu.KotlinLogging ...@@ -4,7 +4,6 @@ import mu.KotlinLogging
import org.apache.kafka.clients.admin.AdminClient import org.apache.kafka.clients.admin.AdminClient
import org.apache.kafka.clients.admin.ListTopicsResult import org.apache.kafka.clients.admin.ListTopicsResult
import org.apache.kafka.clients.admin.NewTopic import org.apache.kafka.clients.admin.NewTopic
import java.util.*
private val logger = KotlinLogging.logger {} private val logger = KotlinLogging.logger {}
......
...@@ -2,4 +2,8 @@ package theodolite.patcher ...@@ -2,4 +2,8 @@ package theodolite.patcher
import io.fabric8.kubernetes.api.model.KubernetesResource import io.fabric8.kubernetes.api.model.KubernetesResource
abstract class AbstractPatcher(k8sResource: KubernetesResource, container: String? = null, variableName: String? = null): Patcher abstract class AbstractPatcher(
k8sResource: KubernetesResource,
container: String? = null,
variableName: String? = null
) : Patcher
...@@ -6,12 +6,18 @@ import io.fabric8.kubernetes.api.model.EnvVarSource ...@@ -6,12 +6,18 @@ import io.fabric8.kubernetes.api.model.EnvVarSource
import io.fabric8.kubernetes.api.model.KubernetesResource import io.fabric8.kubernetes.api.model.KubernetesResource
import io.fabric8.kubernetes.api.model.apps.Deployment import io.fabric8.kubernetes.api.model.apps.Deployment
class EnvVarPatcher(private val k8sResource: KubernetesResource, private val container: String, private val variableName: String): AbstractPatcher(k8sResource, container, variableName) { class EnvVarPatcher(
private val k8sResource: KubernetesResource,
private val container: String,
private val variableName: String
) : AbstractPatcher(k8sResource, container, variableName) {
override fun <String> patch(value: String) { override fun <String> patch(value: String) {
if (k8sResource is Deployment) { if (k8sResource is Deployment) {
this.setEnv(k8sResource, this.container, this.setEnv(
mapOf(this.variableName to value) as Map<kotlin.String, kotlin.String>) k8sResource, this.container,
mapOf(this.variableName to value) as Map<kotlin.String, kotlin.String>
)
} }
} }
...@@ -43,6 +49,4 @@ class EnvVarPatcher(private val k8sResource: KubernetesResource, private val con ...@@ -43,6 +49,4 @@ class EnvVarPatcher(private val k8sResource: KubernetesResource, private val con
workloadDeployment.spec.template.spec.containers.filter { it.name == containerName } workloadDeployment.spec.template.spec.containers.filter { it.name == containerName }
.forEach { setContainerEnv(it, map) } .forEach { setContainerEnv(it, map) }
} }
} }
...@@ -4,7 +4,8 @@ import io.fabric8.kubernetes.api.model.KubernetesResource ...@@ -4,7 +4,8 @@ import io.fabric8.kubernetes.api.model.KubernetesResource
import io.fabric8.kubernetes.api.model.apps.Deployment import io.fabric8.kubernetes.api.model.apps.Deployment
import io.fabric8.kubernetes.api.model.apps.StatefulSet import io.fabric8.kubernetes.api.model.apps.StatefulSet
class ImagePatcher(private val k8sResource: KubernetesResource, private val container: String): AbstractPatcher(k8sResource, container) { class ImagePatcher(private val k8sResource: KubernetesResource, private val container: String) :
AbstractPatcher(k8sResource, container) {
override fun <String> patch(imagePath: String) { override fun <String> patch(imagePath: String) {
if (k8sResource is Deployment) { if (k8sResource is Deployment) {
......
...@@ -3,7 +3,8 @@ package theodolite.patcher ...@@ -3,7 +3,8 @@ package theodolite.patcher
import io.fabric8.kubernetes.api.model.KubernetesResource import io.fabric8.kubernetes.api.model.KubernetesResource
import io.fabric8.kubernetes.api.model.apps.Deployment import io.fabric8.kubernetes.api.model.apps.Deployment
class NodeSelectorPatcher(private val k8sResource: KubernetesResource, private val variableName: String): AbstractPatcher(k8sResource, variableName){ class NodeSelectorPatcher(private val k8sResource: KubernetesResource, private val variableName: String) :
AbstractPatcher(k8sResource, variableName) {
override fun <String> patch(value: String) { override fun <String> patch(value: String) {
if (k8sResource is Deployment) { if (k8sResource is Deployment) {
k8sResource.spec.template.spec.nodeSelector = mapOf(variableName to value as kotlin.String) k8sResource.spec.template.spec.nodeSelector = mapOf(variableName to value as kotlin.String)
......
...@@ -3,17 +3,28 @@ package theodolite.patcher ...@@ -3,17 +3,28 @@ package theodolite.patcher
import io.fabric8.kubernetes.api.model.KubernetesResource import io.fabric8.kubernetes.api.model.KubernetesResource
import theodolite.util.PatcherDefinition import theodolite.util.PatcherDefinition
import theodolite.util.TypeName import theodolite.util.TypeName
import java.lang.IllegalArgumentException
class PatcherManager { class PatcherManager {
private fun createK8sPatcher(patcherDefinition: PatcherDefinition, k8sResources: List<Pair<String, KubernetesResource>>): Patcher { private fun createK8sPatcher(
val resource = k8sResources.filter { it.first == patcherDefinition.resource}.map { resource -> resource.second }[0] patcherDefinition: PatcherDefinition,
k8sResources: List<Pair<String, KubernetesResource>>
): Patcher {
val resource =
k8sResources.filter { it.first == patcherDefinition.resource }.map { resource -> resource.second }[0]
return when (patcherDefinition.type) { return when (patcherDefinition.type) {
"ReplicaPatcher" -> ReplicaPatcher(resource) "ReplicaPatcher" -> ReplicaPatcher(resource)
"EnvVarPatcher" -> EnvVarPatcher(resource, patcherDefinition.container, patcherDefinition.variableName) "EnvVarPatcher" -> EnvVarPatcher(resource, patcherDefinition.container, patcherDefinition.variableName)
"NodeSelectorPatcher" -> NodeSelectorPatcher(resource, patcherDefinition.variableName) "NodeSelectorPatcher" -> NodeSelectorPatcher(resource, patcherDefinition.variableName)
"ResourceLimitPatcher" -> ResourceLimitPatcher(resource, patcherDefinition.container, patcherDefinition.variableName) "ResourceLimitPatcher" -> ResourceLimitPatcher(
"ResourceRequestPatcher" -> ResourceRequestPatcher(resource, patcherDefinition.container, patcherDefinition.variableName) resource,
patcherDefinition.container,
patcherDefinition.variableName
)
"ResourceRequestPatcher" -> ResourceRequestPatcher(
resource,
patcherDefinition.container,
patcherDefinition.variableName
)
else -> throw IllegalArgumentException("Patcher type ${patcherDefinition.type} not found") else -> throw IllegalArgumentException("Patcher type ${patcherDefinition.type} not found")
} }
} }
...@@ -25,17 +36,24 @@ class PatcherManager { ...@@ -25,17 +36,24 @@ class PatcherManager {
} }
/** /**
* This function first creates a patcher definition and then patches the list of resources based on this patcher definition * This function first creates a patcher definition and
* then patches the list of resources based on this patcher definition
* *
* @param type Patcher type, for example "EnvVarPatcher" * @param type Patcher type, for example "EnvVarPatcher"
* @param patcherTypes List of patcher types definitions, for example for resources and threads * @param patcherTypes List of patcher types definitions, for example for resources and threads
* @param resources List of K8s resources, a patcher takes the resources that are needed * @param resources List of K8s resources, a patcher takes the resources that are needed
* @param value The value to patch * @param value The value to patch
*/ */
fun createAndApplyPatcher(type: String, patcherTypes: List<TypeName>, resources: List<Pair<String, KubernetesResource>>, value: Any) { fun createAndApplyPatcher(
type: String,
patcherTypes: List<TypeName>,
resources: List<Pair<String, KubernetesResource>>,
value: Any
) {
this.getPatcherDef(type, patcherTypes) this.getPatcherDef(type, patcherTypes)
.forEach { patcherDef -> .forEach { patcherDef ->
createK8sPatcher(patcherDef, resources).patch(value) } createK8sPatcher(patcherDef, resources).patch(value)
}
} }
/** /**
...@@ -45,8 +63,11 @@ class PatcherManager { ...@@ -45,8 +63,11 @@ class PatcherManager {
* @param resources List of patcher types definitions, for example for resources and threads * @param resources List of patcher types definitions, for example for resources and threads
* @param value The value to patch * @param value The value to patch
*/ */
fun applyPatcher(patcherDefinition: List<PatcherDefinition>, resources: List<Pair<String, KubernetesResource>>, value: Any) { fun applyPatcher(
patcherDefinition: List<PatcherDefinition>,
resources: List<Pair<String, KubernetesResource>>,
value: Any
) {
patcherDefinition.forEach { def -> this.createK8sPatcher(def, resources).patch(value) } patcherDefinition.forEach { def -> this.createK8sPatcher(def, resources).patch(value) }
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment