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

Applied Code Reviews for TopicManager and WorkloadGeneratorStateCleaner

parent 4ffaa587
No related branches found
No related tags found
4 merge requests!159Re-implementation of Theodolite with Kotlin/Quarkus,!157Update Graal Image in CI pipeline,!83WIP: Re-implementation of Theodolite with Kotlin/Quarkus,!78Resolve "Implement Quarkus/Kotlin protype"
......@@ -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
}
......@@ -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? {
......
......@@ -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])
......
......@@ -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) {}
......
<!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
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