From 7b55c6d193f2b0b093a61d851810d9dd616b75a3 Mon Sep 17 00:00:00 2001 From: lorenz <stu203404@mail.uni-kiel.de> Date: Sat, 6 Feb 2021 02:12:29 +0100 Subject: [PATCH] Applied Code Reviews for TopicManager and WorkloadGeneratorStateCleaner --- .../theodolite/execution/BenchmarkExecutor.kt | 4 +- .../kotlin/theodolite/k8s/TopicManager.kt | 23 +- .../kotlin/theodolite/k8s/UC1Benchmark.kt | 6 +- .../k8s/WorkloadGeneratorStateCleaner.kt | 49 ++-- .../resources/META-INF/resources/index.html | 242 ------------------ 5 files changed, 53 insertions(+), 271 deletions(-) delete mode 100644 theodolite-quarkus/src/main/resources/META-INF/resources/index.html diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt b/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt index 751e2d322..2cc54a25c 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt @@ -25,7 +25,7 @@ abstract class BenchmarkExecutor(val benchmark: Benchmark, val results: Results, * @param res resources to be tested. * @return True, if the number of resources are suitable for the given load, false otherwise. */ - abstract fun runExperiment(load: LoadDimension, res: Resource): Boolean; + abstract fun runExperiment(load: LoadDimension, res: Resource): Boolean /** * Wait while the benchmark is running and log the number of minutes executed every 1 minute. @@ -37,4 +37,4 @@ abstract class BenchmarkExecutor(val benchmark: Benchmark, val results: Results, logger.info { "Executed: $i minutes" } } } -} \ No newline at end of file +} diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/TopicManager.kt b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/TopicManager.kt index 4f75298f3..fe1f4f89c 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/TopicManager.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/TopicManager.kt @@ -8,6 +8,10 @@ import org.apache.kafka.clients.admin.NewTopic private val logger = KotlinLogging.logger {} +/** + * Manages the topics related tasks + * @param bootstrapServers Ip of the kafka server + */ class TopicManager(bootstrapServers: String) { private val props = hashMapOf<String, Any>(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG to bootstrapServers) lateinit var kafkaAdmin: AdminClient @@ -16,10 +20,15 @@ class TopicManager(bootstrapServers: String) { try { kafkaAdmin = AdminClient.create(props) } catch (e: Exception) { - logger.error {e.toString()} + logger.error { e.toString() } } } + /** + * Creates topics. + * @param topics Map that holds a numPartition for each topic it should create + * @param replicationFactor + */ fun createTopics(topics: Map<String, Int>, replicationFactor: Short) { val newTopics = mutableSetOf<NewTopic>() @@ -28,7 +37,7 @@ class TopicManager(bootstrapServers: String) { newTopics.add(tops) } kafkaAdmin.createTopics(newTopics) - logger.info {"Topics created"} + logger.info { "Topics created" } } fun createTopics(topics: List<String>, numPartitions: Int, replicationFactor: Short) { @@ -39,9 +48,13 @@ class TopicManager(bootstrapServers: String) { newTopics.add(tops) } kafkaAdmin.createTopics(newTopics) - logger.info {"Creation of $topics started"} + logger.info { "Creation of $topics started" } } + /** + * Deletes topics. + * @param topics + */ fun deleteTopics(topics: List<String>) { val result = kafkaAdmin.deleteTopics(topics) @@ -49,9 +62,9 @@ class TopicManager(bootstrapServers: String) { try { result.all().get() } catch (ex: Exception) { - logger.error {ex.toString()} + logger.error { ex.toString() } } - logger.info {"Topics deleted"} + logger.info { "Topics deleted" } } fun getTopics(): ListTopicsResult? { diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/UC1Benchmark.kt b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/UC1Benchmark.kt index 7e1347973..c8766c2fa 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/UC1Benchmark.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/UC1Benchmark.kt @@ -27,9 +27,9 @@ class UC1Benchmark(config: UC1BenchmarkConfig) : Benchmark(config) { private var wgDeployment: Deployment private var configMap: ConfigMap - init { - this.workloadGeneratorStateCleaner = WorkloadGeneratorStateCleaner(this.config.zookeeperConnectionString) + this.workloadGeneratorStateCleaner = + WorkloadGeneratorStateCleaner(this.config.zookeeperConnectionString, path = "/workload-generation") this.topicManager = TopicManager(this.config.kafkaIPConnectionString) this.kubernetesClient = DefaultKubernetesClient().inNamespace("default") this.yamlLoader = YamlLoader(this.kubernetesClient) @@ -83,7 +83,7 @@ class UC1Benchmark(config: UC1BenchmarkConfig) : Benchmark(config) { // TODO ("calculate number of required instances") - val requiredInstances: Int = 1 + val requiredInstances = 1 val environmentVariables: MutableMap<String, String> = mutableMapOf() //environmentVariables.put("KAFKA_BOOTSTRAP_SERVERS", this.config.kafkaIPConnectionString) //environmentVariables.put("ZK_HOST", this.config.zookeeperConnectionString.split(":")[0]) diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/WorkloadGeneratorStateCleaner.kt b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/WorkloadGeneratorStateCleaner.kt index 98c11167a..e1e2c5d3e 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/WorkloadGeneratorStateCleaner.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/WorkloadGeneratorStateCleaner.kt @@ -5,58 +5,69 @@ import org.apache.zookeeper.KeeperException import org.apache.zookeeper.WatchedEvent import org.apache.zookeeper.Watcher import org.apache.zookeeper.ZooKeeper +import java.time.Duration private val logger = KotlinLogging.logger {} - -class WorkloadGeneratorStateCleaner(ip: String) { - private val path = "/workload-generation" - private val sessionTimeout = 60 - private val retryTime = 3000L +/** + * Resets the workloadgenerator states in zookeper (and potetially watches for Zookeper events) + * + * @param ip of zookeeper + * @param path path of the zookeeper node + */ +class WorkloadGeneratorStateCleaner(ip: String, val path: String) { + private val timeout: Duration = Duration.ofMillis(500) + private val retryAfter: Duration = Duration.ofSeconds(5) lateinit var zookeeperClient: ZooKeeper init { try { - val watcher: Watcher = ZookeeperWatcher() // defined below - zookeeperClient = ZooKeeper(ip, sessionTimeout, watcher) + val watcher: Watcher = ZookeeperWatcher() // defined below + zookeeperClient = ZooKeeper(ip, timeout.toMillis().toInt(), watcher) } catch (e: Exception) { - logger.error {e.toString()} + logger.error { e.toString() } } } + /** + * Deletes all Zookeeper nodes with the corresponding path. + */ fun deleteAll() { var deleted = false while (!deleted) { - - // try { - zookeeperClient.delete(path, -1) + zookeeperClient.delete(this.path, -1) } catch (ex: Exception) { - logger.error {ex.toString()} + logger.error { ex.toString() } } try { - val clients = zookeeperClient.getChildren(path, true) + // get list of all nodes of the given path + val clients = zookeeperClient.getChildren(this.path, true) if (clients.isEmpty()) { - break; + deleted = true + break } } catch (ex: Exception) { when (ex) { + // indicates that there are no nodes to delete left is KeeperException -> { deleted = true } is InterruptedException -> { - logger.error {ex.toString()} + logger.error { ex.toString() } } } } - Thread.sleep(retryTime) - logger.info {"ZooKeeper reset was not successful. Retrying in 5s"} + Thread.sleep(retryAfter.toMillis()) + logger.info { "ZooKeeper reset was not successful. Retrying in 5s" } } - - logger.info {"ZooKeeper reset was successful"} + logger.info { "ZooKeeper reset was successful" } } + /** + * Currently empty, could be used to watch(and react) on certain zookeeper events + */ private class ZookeeperWatcher : Watcher { override fun process(event: WatchedEvent) {} diff --git a/theodolite-quarkus/src/main/resources/META-INF/resources/index.html b/theodolite-quarkus/src/main/resources/META-INF/resources/index.html deleted file mode 100644 index 1a04c85cd..000000000 --- a/theodolite-quarkus/src/main/resources/META-INF/resources/index.html +++ /dev/null @@ -1,242 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -<head> - <meta charset="UTF-8"> - <title>theodolite-quarkus - 1.0.0-SNAPSHOT</title> - <style> - h1, h2, h3, h4, h5, h6 { - margin-bottom: 0.5rem; - font-weight: 400; - line-height: 1.5; - } - - h1 { - font-size: 2.5rem; - } - - h2 { - font-size: 2rem - } - - h3 { - font-size: 1.75rem - } - - h4 { - font-size: 1.5rem - } - - h5 { - font-size: 1.25rem - } - - h6 { - font-size: 1rem - } - - .lead { - font-weight: 300; - font-size: 2rem; - } - - .banner { - font-size: 2.7rem; - margin: 0; - padding: 2rem 1rem; - background-color: #0d1c2c; - color: white; - } - - body { - margin: 0; - font-family: -apple-system, system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - } - - code { - font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; - font-size: 87.5%; - color: #e83e8c; - word-break: break-word; - } - - .left-column { - padding: .75rem; - max-width: 75%; - min-width: 55%; - } - - .right-column { - padding: .75rem; - max-width: 25%; - } - - .container { - display: flex; - width: 100%; - } - - li { - margin: 0.75rem; - } - - .right-section { - margin-left: 1rem; - padding-left: 0.5rem; - } - - .right-section h3 { - padding-top: 0; - font-weight: 200; - } - - .right-section ul { - border-left: 0.3rem solid #71aeef; - list-style-type: none; - padding-left: 0; - } - - .examples { - display: flex; - flex-wrap: wrap; - margin: 20px 0 20px -40px; - } - - .example { - display: flex; - margin-left: 20px; - margin-bottom: 20px; - flex-direction: column; - width: 350px; - background-color: #205894; - color: white; - } - - .example code { - color: lightgrey; - } - - .example-header { - padding: 20px; - display: flex; - position: relative; - } - - .example-header h4 { - margin: 0; - font-size: 1.4rem; - flex-grow: 1; - line-height: 1.5; - } - - .example-description { - padding: 0 20px; - flex-grow: 1; - } - - .example-paths { - display: flex; - flex-direction: column; - } - - .example-paths a { - display: block; - background-color: transparent; - font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; - color: white; - padding: 10px; - text-decoration: none; - } - - .example-paths a:before { - content: '⇨'; - font-weight: bold; - font-size: 1.5rem; - margin: 20px; - } - - .example-paths a:hover { - background-color: #0d1c2c; - } - - .guide-link { - background-color: #71aeef; - position: absolute; - color: white; - text-decoration: none; - top: 0; - right: 0; - padding: 7px; - font-weight: bold; - } - - .guide-link:hover { - background-color: #0d1c2c; - } - </style> -</head> -<body> - -<div class="banner lead"> - Your new Cloud-Native application is ready! -</div> - -<div class="container"> - <div class="left-column"> - <p class="lead"> Congratulations, you have created a new Quarkus cloud application.</p> - - <h2>Why do you see this?</h2> - - <p>This page is served by Quarkus. The source is in - <code>src/main/resources/META-INF/resources/index.html</code>.</p> - - <h2>What can I do from here?</h2> - - <p>If not already done, run the application in <em>dev mode</em> using: <code>./gradlew quarkusDev</code>. - </p> - <ul> - <li>Play with your example code in <code>src/main/kotlin</code>: - <div class="examples"> -<div class="example"> - <div class="example-header"> - <h4>RESTEasy JAX-RS</h4> - <a href="https://quarkus.io/guides/rest-json" target="_blank" class="guide-link">Guide</a> - </div> - <div class="example-description"> - <p>A Hello World RESTEasy resource</p> - - </div> - <div class="example-paths"> - <a href="/hello-resteasy" class="path-link" target="_blank">GET /hello-resteasy</a> - </div> -</div> - - </div> - </li> - <li>Your static assets are located in <code>src/main/resources/META-INF/resources</code>.</li> - <li>Configure your application in <code>src/main/resources/application.properties</code>.</li> - </ul> - <h2>Do you like Quarkus?</h2> - <p>Go give it a star on <a href="https://github.com/quarkusio/quarkus">GitHub</a>.</p> - </div> - <div class="right-column"> - <div class="right-section"> - <h3>Application</h3> - <ul> - <li>GroupId: theodolite</li> - <li>ArtifactId: theodolite-quarkus</li> - <li>Version: 1.0.0-SNAPSHOT</li> - <li>Quarkus Version: 1.10.3.Final</li> - </ul> - </div> - <div class="right-section"> - <h3>Next steps</h3> - <ul> - <li><a href="https://quarkus.io/guides/gradle-tooling" target="_blank">Setup your IDE</a></li> - <li><a href="https://quarkus.io/guides/getting-started.html" target="_blank">Getting started</a></li> - <li><a href="https://quarkus.io" target="_blank">Quarkus Web Site</a></li> - </ul> - </div> - </div> -</div> -</body> -</html> \ No newline at end of file -- GitLab