Skip to content
Snippets Groups Projects
Commit db0c6bb8 authored by Sören Henning's avatar Sören Henning
Browse files

Merge branch 'quarkus-upgrade' into 'master'

Upgrade Quarkus

Closes #215

See merge request !213
parents 0dfca34d eaff2d73
No related branches found
No related tags found
1 merge request!213Upgrade Quarkus
Pipeline #6051 failed
Showing
with 111 additions and 103 deletions
......@@ -31,3 +31,6 @@ nb-configuration.xml
# patch
*.orig
*.rej
# Local environment
.env
......@@ -12,14 +12,8 @@ You can run your application in dev mode using:
./gradlew quarkusDev
```
### Hint for running with k3s (or k3d)
> **_NOTE:_** Quarkus now ships with a Dev UI, which is available in dev mode only at http://localhost:8080/q/dev/.
You may need to add the following dependencies to the `build.gradle` file when running Theodolite with k3s.
```
implementation 'org.bouncycastle:bcprov-ext-jdk15on:1.68'
implementation 'org.bouncycastle:bcpkix-jdk15on:1.68'
```
## Packaging and running the application
......@@ -59,7 +53,7 @@ Or, if you don't have GraalVM installed, you can run the native executable build
You can then execute your native executable with:
```./build/theodolite-0.7.0-SNAPSHOT-runner```
If you want to learn more about building native executables, please consult <https://quarkus.io/guides/gradle-tooling>.
If you want to learn more about building native executables, please consult https://quarkus.io/guides/gradle-tooling.
## Build docker images
......
plugins {
id 'org.jetbrains.kotlin.jvm' version "1.3.72"
id "org.jetbrains.kotlin.plugin.allopen" version "1.3.72"
id 'org.jetbrains.kotlin.jvm' version "1.5.31"
id "org.jetbrains.kotlin.plugin.allopen" version "1.5.31"
id 'io.quarkus'
id "io.gitlab.arturbosch.detekt" version "1.15.0" //For code style
id "org.jlleitschuh.gradle.ktlint" version "10.0.0" // same as above
id "io.gitlab.arturbosch.detekt" version "1.15.0"
id "org.jlleitschuh.gradle.ktlint" version "10.0.0"
}
repositories {
......@@ -18,21 +18,28 @@ dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
implementation 'io.quarkus:quarkus-arc'
implementation 'io.quarkus:quarkus-resteasy'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'org.slf4j:slf4j-simple:1.7.29'
implementation 'io.github.microutils:kotlin-logging:1.12.0'
implementation('io.fabric8:kubernetes-client:5.4.1'){force = true}
implementation('io.fabric8:kubernetes-model-core:5.4.1'){force = true}
implementation('io.fabric8:kubernetes-model-common:5.4.1'){force = true}
implementation 'org.apache.kafka:kafka-clients:2.7.0'
implementation 'io.quarkus:quarkus-kubernetes-client'
implementation 'org.bouncycastle:bcprov-ext-jdk15on:1.69'
implementation 'org.bouncycastle:bcpkix-jdk15on:1.69'
implementation 'com.google.code.gson:gson:2.8.9'
implementation 'org.slf4j:slf4j-simple:1.7.32'
implementation 'io.github.microutils:kotlin-logging:2.1.16'
//implementation('io.fabric8:kubernetes-client:5.4.1'){force = true}
//implementation('io.fabric8:kubernetes-model-core:5.4.1'){force = true}
//implementation('io.fabric8:kubernetes-model-common:5.4.1'){force = true}
implementation 'org.apache.kafka:kafka-clients:2.8.0'
implementation 'khttp:khttp:1.0.0'
compile 'junit:junit:4.12'
// compile 'junit:junit:4.12'
testImplementation 'io.quarkus:quarkus-junit5'
testImplementation 'io.quarkus:quarkus-test-kubernetes-client'
testImplementation 'io.rest-assured:rest-assured'
testImplementation 'org.junit-pioneer:junit-pioneer:1.4.0'
testImplementation ('io.fabric8:kubernetes-server-mock:5.4.1'){force = true}
testImplementation 'org.junit-pioneer:junit-pioneer:1.5.0'
//testImplementation 'io.fabric8:kubernetes-server-mock:5.10.1'
testImplementation "org.mockito.kotlin:mockito-kotlin:4.0.0"
}
group 'theodolite'
......@@ -57,6 +64,7 @@ compileKotlin {
compileTestKotlin {
kotlinOptions.jvmTarget = JavaVersion.VERSION_11
}
detekt {
failFast = true // fail build on any finding
buildUponDefaultConfig = true
......
#Gradle properties
quarkusPluginVersion=2.5.2.Final
quarkusPlatformArtifactId=quarkus-bom
quarkusPluginId=io.quarkus
quarkusPluginVersion=1.10.3.Final
quarkusPlatformGroupId=io.quarkus
quarkusPlatformArtifactId=quarkus-universe-bom
quarkusPlatformVersion=1.10.3.Final
quarkusPlatformGroupId=io.quarkus.platform
quarkusPlatformVersion=2.5.2.Final
org.gradle.logging.level=INFO
\ No newline at end of file
#org.gradle.logging.level=INFO
\ No newline at end of file
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
File mode changed from 100755 to 100644
......@@ -14,14 +14,14 @@
# docker run -i --rm -p 8080:8080 quarkus/theodolite-jvm
#
# If you want to include the debug port into your docker image
# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5050
# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5005
#
# Then run the container using :
#
# docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/theodolite-jvm
#
###
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.4
ARG JAVA_PACKAGE=java-11-openjdk-headless
ARG RUN_JAVA_VERSION=1.3.8
......@@ -38,14 +38,18 @@ RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \
&& curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \
&& chown 1001 /deployments/run-java.sh \
&& chmod 540 /deployments/run-java.sh \
&& echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security
&& echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/conf/security/java.security
# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
COPY build/lib/* /deployments/lib/
COPY build/*-runner.jar /deployments/app.jar
# We make four distinct layers so if there are application changes the library layers can be re-used
COPY --chown=1001 build/quarkus-app/lib/ /deployments/lib/
COPY --chown=1001 build/quarkus-app/*.jar /deployments/
COPY --chown=1001 build/quarkus-app/app/ /deployments/app/
COPY --chown=1001 build/quarkus-app/quarkus/ /deployments/quarkus/
EXPOSE 8080
USER 1001
ENTRYPOINT [ "/deployments/run-java.sh" ]
......@@ -3,25 +3,25 @@
#
# Before building the container image run:
#
# ./gradlew build -Dquarkus.package.type=fast-jar
# ./gradlew build -Dquarkus.package.type=legacy-jar
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.fast-jar -t quarkus/theodolite-fast-jar .
# docker build -f src/main/docker/Dockerfile.legacy-jar -t quarkus/theodolite-legacy-jar .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/theodolite-fast-jar
# docker run -i --rm -p 8080:8080 quarkus/theodolite-legacy-jar
#
# If you want to include the debug port into your docker image
# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5050
# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5005
#
# Then run the container using :
#
# docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/theodolite-fast-jar
# docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/theodolite-legacy-jar
#
###
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.4
ARG JAVA_PACKAGE=java-11-openjdk-headless
ARG RUN_JAVA_VERSION=1.3.8
......@@ -38,15 +38,12 @@ RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \
&& curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \
&& chown 1001 /deployments/run-java.sh \
&& chmod 540 /deployments/run-java.sh \
&& echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security
&& echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/conf/security/java.security
# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
# We make four distinct layers so if there are application changes the library layers can be re-used
COPY --chown=1001 build/quarkus-app/lib/ /deployments/lib/
COPY --chown=1001 build/quarkus-app/*.jar /deployments/
COPY --chown=1001 build/quarkus-app/app/ /deployments/app/
COPY --chown=1001 build/quarkus-app/quarkus/ /deployments/quarkus/
COPY build/lib/* /deployments/lib/
COPY build/*-runner.jar /deployments/app.jar
EXPOSE 8080
USER 1001
......
......@@ -14,8 +14,8 @@
# docker run -i --rm -p 8080:8080 quarkus/theodolite
#
###
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3
WORKDIR /deployments
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.4
WORKDIR /deployments/
RUN chown 1001 /deployments \
&& chmod "g+rwX" /deployments \
&& chown 1001:root /deployments
......
####
# This Dockerfile is used in order to build a distroless container that runs the Quarkus application in native (no JVM) mode
#
# Before building the container image run:
#
# ./gradlew build -Dquarkus.package.type=native
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.native-distroless -t quarkus/theodolite .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/theodolite
#
###
FROM quay.io/quarkus/quarkus-distroless-image:1.0
WORKDIR /deployments/
COPY build/*-runner /deployments/application
EXPOSE 8080
USER nonroot
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
......@@ -5,14 +5,10 @@ import io.fabric8.kubernetes.api.model.KubernetesResource
import io.fabric8.kubernetes.client.KubernetesClientException
import io.fabric8.kubernetes.client.NamespacedKubernetesClient
import io.quarkus.runtime.annotations.RegisterForReflection
import mu.KotlinLogging
import theodolite.k8s.resourceLoader.K8sResourceLoaderFromString
import theodolite.util.DeploymentFailedException
import theodolite.util.YamlParserFromString
import java.lang.IllegalArgumentException
import java.lang.IllegalStateException
private val logger = KotlinLogging.logger {}
@RegisterForReflection
@JsonDeserialize
......@@ -20,27 +16,23 @@ class ConfigMapResourceSet: ResourceSet, KubernetesResource {
lateinit var name: String
lateinit var files: List<String> // load all files, iff files is not set
@OptIn(ExperimentalStdlibApi::class)
override fun getResourceSet(client: NamespacedKubernetesClient): Collection<Pair<String, KubernetesResource>> {
val loader = K8sResourceLoaderFromString(client)
var resources: Map<String, String>
try {
resources = client
resources = (client
.configMaps()
.withName(name)
.get()
.get() ?: throw DeploymentFailedException("Cannot find ConfigMap with name '$name'."))
.data
.filter { it.key.endsWith(".yaml") } // consider only yaml files, e.g. ignore readme files
.filter { it.key.endsWith(".yaml") }
} catch (e: KubernetesClientException) {
throw DeploymentFailedException("can not find or read configmap: $name", e)
} catch (e: IllegalStateException) {
throw DeploymentFailedException("can not find configmap or data section is null $name", e)
throw DeploymentFailedException("Cannot find or read ConfigMap with name '$name'.", e)
}
if (::files.isInitialized){
resources = resources
.filter { files.contains(it.key) }
resources = resources.filter { files.contains(it.key) }
if (resources.size != files.size) {
throw DeploymentFailedException("Could not find all specified Kubernetes manifests files")
......@@ -57,7 +49,7 @@ class ConfigMapResourceSet: ResourceSet, KubernetesResource {
it.second.key,
loader.loadK8sResource(it.first, it.second.value)) }
} catch (e: IllegalArgumentException) {
throw DeploymentFailedException("Can not creat resource set from specified configmap", e)
throw DeploymentFailedException("Can not create resource set from specified configmap", e)
}
}
......
......@@ -2,10 +2,8 @@ package theodolite.benchmark
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import io.fabric8.kubernetes.api.model.KubernetesResource
import io.fabric8.kubernetes.client.DefaultKubernetesClient
import io.fabric8.kubernetes.client.NamespacedKubernetesClient
import io.quarkus.runtime.annotations.RegisterForReflection
import mu.KotlinLogging
import theodolite.k8s.resourceLoader.K8sResourceLoaderFromFile
import theodolite.util.DeploymentFailedException
import theodolite.util.YamlParserFromFile
......@@ -13,8 +11,6 @@ import java.io.File
import java.io.FileNotFoundException
import java.lang.IllegalArgumentException
private val logger = KotlinLogging.logger {}
@RegisterForReflection
@JsonDeserialize
class FileSystemResourceSet: ResourceSet, KubernetesResource {
......
package theodolite.benchmark
import com.fasterxml.jackson.annotation.JsonInclude
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import io.fabric8.kubernetes.api.model.KubernetesResource
import io.fabric8.kubernetes.client.DefaultKubernetesClient
......@@ -44,7 +43,7 @@ class KubernetesBenchmark : KubernetesResource, Benchmark {
lateinit var infrastructure: Resources
lateinit var sut: Resources
lateinit var loadGenerator: Resources
var namespace = System.getenv("NAMESPACE") ?: DEFAULT_NAMESPACE
private var namespace = System.getenv("NAMESPACE") ?: DEFAULT_NAMESPACE
@Transient
private var client: NamespacedKubernetesClient = DefaultKubernetesClient().inNamespace(namespace)
......
......@@ -6,7 +6,6 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import io.fabric8.kubernetes.api.model.KubernetesResource
import io.fabric8.kubernetes.client.NamespacedKubernetesClient
import io.quarkus.runtime.annotations.RegisterForReflection
import mu.KotlinLogging
import theodolite.util.DeploymentFailedException
@JsonDeserialize
......
package theodolite.evaluation
import mu.KotlinLogging
import theodolite.benchmark.BenchmarkExecution
import theodolite.util.EvaluationFailedException
import theodolite.util.IOHandler
......@@ -12,8 +11,6 @@ import java.time.Instant
import java.util.*
import java.util.regex.Pattern
private val logger = KotlinLogging.logger {}
/**
* Contains the analysis. Fetches a metric from Prometheus, documents it, and evaluates it.
* @param slo Slo that is used for the analysis.
......@@ -81,6 +78,6 @@ class AnalysisExecutor(
val noWhitespace: String = WHITESPACE.matcher(this).replaceAll("-")
val normalized: String = Normalizer.normalize(noWhitespace, Normalizer.Form.NFD)
val slug: String = NONLATIN.matcher(normalized).replaceAll("")
return slug.toLowerCase(Locale.ENGLISH)
return slug.lowercase(Locale.ENGLISH)
}
}
......@@ -2,6 +2,5 @@ package theodolite.execution
enum class ExecutionModes(val value: String) {
OPERATOR("operator"),
YAML_EXECUTOR("yaml-executor"),
STANDALONE("standalone")
}
\ No newline at end of file
......@@ -17,8 +17,8 @@ object Main {
val mode = Configuration.EXECUTION_MODE
logger.info { "Start Theodolite with mode $mode" }
when (mode.toLowerCase()) {
ExecutionModes.STANDALONE.value, ExecutionModes.YAML_EXECUTOR.value -> TheodoliteStandalone().start() // TODO remove standalone (#209)
when (mode.lowercase()) {
ExecutionModes.STANDALONE.value -> TheodoliteStandalone().start()
ExecutionModes.OPERATOR.value -> TheodoliteOperator().start()
else -> {
logger.error { "MODE $mode not found" }
......
......@@ -14,14 +14,13 @@ private val logger = KotlinLogging.logger {}
* @property benchmarkExecution
* @property benchmark
*/
class Shutdown(private val benchmarkExecution: BenchmarkExecution, private val benchmark: KubernetesBenchmark) :
Thread() {
class Shutdown(private val benchmarkExecution: BenchmarkExecution, private val benchmark: KubernetesBenchmark) {
/**
* Run
* Delete all Kubernetes resources which are related to the execution and the benchmark.
*/
override fun run() {
fun run() {
// Build Configuration to teardown
try {
logger.info { "Received shutdown signal -> Shutting down" }
......@@ -34,9 +33,7 @@ class Shutdown(private val benchmarkExecution: BenchmarkExecution, private val b
afterTeardownDelay = 5L
)
deployment.teardown()
logger.info {
"Finished teardown of all benchmark resources."
}
logger.info { "Finished teardown of all benchmark resources." }
} catch (e: Exception) {
logger.warn {
"Could not delete all specified resources from Kubernetes. " +
......
......@@ -12,30 +12,30 @@ import mu.KotlinLogging
import java.lang.Thread.sleep
private val logger = KotlinLogging.logger {}
abstract class AbstractStateHandler<T, L, D>(
private const val MAX_RETRIES: Int = 5
abstract class AbstractStateHandler<T : HasMetadata>(
private val client: NamespacedKubernetesClient,
private val crd: Class<T>,
private val crdList: Class<L>
) : StateHandler<T> where T : CustomResource<*, *>?, T : HasMetadata, T : Namespaced, L : KubernetesResourceList<T> {
private val crd: Class<T>
) {
private val crdClient: MixedOperation<T, L, Resource<T>> =
this.client.customResources(this.crd, this.crdList)
private val crdClient: MixedOperation<T, KubernetesResourceList<T>, Resource<T>> = this.client.resources(this.crd)
@Synchronized
override fun setState(resourceName: String, f: (T) -> T?) {
fun setState(resourceName: String, f: (T) -> T?) {
try {
this.crdClient
.list().items
.filter { it.metadata.name == resourceName }
.map { customResource -> f(customResource) }
.forEach { this.crdClient.updateStatus(it) }
val resource = this.crdClient.withName(resourceName).get()
if (resource != null) {
val resourcePatched = f(resource)
this.crdClient.patchStatus(resourcePatched)
}
} catch (e: KubernetesClientException) {
logger.warn { "Status cannot be set for resource $resourceName" }
logger.warn(e) { "Status cannot be set for resource $resourceName." }
}
}
@Synchronized
override fun getState(resourceName: String, f: (T) -> String?): String? {
fun getState(resourceName: String, f: (T) -> String?): String? {
return this.crdClient
.list().items
.filter { it.metadata.name == resourceName }
......@@ -44,13 +44,13 @@ abstract class AbstractStateHandler<T, L, D>(
}
@Synchronized
override fun blockUntilStateIsSet(
fun blockUntilStateIsSet(
resourceName: String,
desiredStatusString: String,
f: (T) -> String?,
maxTries: Int
maxRetries: Int = MAX_RETRIES
): Boolean {
for (i in 0.rangeTo(maxTries)) {
for (i in 0.rangeTo(maxRetries)) {
val currentStatus = getState(resourceName, f)
if (currentStatus == desiredStatusString) {
return true
......
......@@ -4,10 +4,9 @@ import io.fabric8.kubernetes.client.NamespacedKubernetesClient
import theodolite.model.crd.*
class BenchmarkStateHandler(val client: NamespacedKubernetesClient) :
AbstractStateHandler<BenchmarkCRD, KubernetesBenchmarkList, ExecutionStatus>(
AbstractStateHandler<BenchmarkCRD>(
client = client,
crd = BenchmarkCRD::class.java,
crdList = KubernetesBenchmarkList::class.java
crd = BenchmarkCRD::class.java
) {
private fun getBenchmarkResourceState() = { cr: BenchmarkCRD -> cr.status.resourceSetsState }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment