diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 5ed0503fa6a3732a934709dd3481d3cc36cadee9..e8dd8fb7e63a49c30f423a6063283352ca526143 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -658,7 +658,7 @@ smoketest-uc4-hazelcastjet:
 
 .theodolite:
   image:
-    name: ghcr.io/graalvm/native-image:java11-21.3.0
+    name: ghcr.io/graalvm/native-image:ol8-java17-22.3.3
     entrypoint: [""]
   variables:
     GRADLE_OPTS: "-Dorg.gradle.daemon=false"
diff --git a/theodolite/.gitignore b/theodolite/.gitignore
index 285b6baee527835a20f0b79f1ecece49b80f7d42..216783d79cafca20c19eca37614f1817765af263 100644
--- a/theodolite/.gitignore
+++ b/theodolite/.gitignore
@@ -34,3 +34,6 @@ nb-configuration.xml
 
 # Local environment
 .env
+
+# Plugin directory
+/.quarkus/cli/plugins/
diff --git a/theodolite/README.md b/theodolite/README.md
index 1d2e0acd52ff6bdfbc30f8d2b291f673f8719356..5bf0a7468a547b0d0de1445af36f432075e258e9 100644
--- a/theodolite/README.md
+++ b/theodolite/README.md
@@ -2,7 +2,7 @@
 
 This project uses Quarkus, the Supersonic Subatomic Java Framework.
 
-If you want to learn more about Quarkus, please visit its website: https://quarkus.io/.
+If you want to learn more about Quarkus, please visit its website: https://quarkus.io/ .
 
 ## Running the application in dev mode
 
@@ -50,8 +50,7 @@ Or, if you don't have GraalVM installed, you can run the native executable build
 ./gradlew build -Dquarkus.package.type=native -Dquarkus.native.container-build=true
 ```
 
-You can then execute your native executable with:
-```./build/theodolite-0.10.0-SNAPSHOT-runner```
+You can then execute your native executable with: `./build/theodolite-0.10.0-SNAPSHOT-runner`
 
 If you want to learn more about building native executables, please consult https://quarkus.io/guides/gradle-tooling.
 
diff --git a/theodolite/build.gradle b/theodolite/build.gradle
index 9a997242adf12eb3e5aa30549088d52cf305ef19..c01f261c7bd3c9e9b62bc7efeb93c492c499ab07 100644
--- a/theodolite/build.gradle
+++ b/theodolite/build.gradle
@@ -1,6 +1,6 @@
 plugins {
-    id 'org.jetbrains.kotlin.jvm' version "1.6.10"
-    id "org.jetbrains.kotlin.plugin.allopen" version "1.6.10"
+    id 'org.jetbrains.kotlin.jvm' version "1.8.22"
+    id "org.jetbrains.kotlin.plugin.allopen" version "1.8.22"
     id 'io.quarkus'
     id "io.gitlab.arturbosch.detekt" version "1.15.0"
     id "org.jlleitschuh.gradle.ktlint" version "10.0.0"
@@ -12,11 +12,15 @@ repositories {
 }
 
 dependencies {
-    implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
+    // Use latest Kubernetes client to use TestStandardHttpClient for exec commands tests
+    implementation platform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
+    implementation enforcedPlatform("io.fabric8:kubernetes-client-bom:6.8.0")
+    // Use default Quarkus once kubernetes-client 6.8.* is integrated
+    //implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
     implementation 'io.quarkus:quarkus-kotlin'
     implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
     implementation 'io.quarkus:quarkus-arc'
-    implementation 'io.quarkus:quarkus-resteasy'
+    //implementation 'io.quarkus:quarkus-resteasy'
     implementation 'io.quarkus:quarkus-kubernetes-client'
 
     implementation 'org.bouncycastle:bcprov-ext-jdk15on:1.69'
@@ -29,6 +33,12 @@ dependencies {
 
     testImplementation 'io.quarkus:quarkus-junit5'
     testImplementation 'io.quarkus:quarkus-test-kubernetes-client'
+    // Used for exec command tests
+    testImplementation ('io.fabric8:kubernetes-client-api') {
+        artifact {
+            classifier = 'tests'
+        }
+    }
     //testImplementation 'io.rest-assured:rest-assured'
     testImplementation 'com.github.tomakehurst:wiremock-jre8:2.35.0'
     testImplementation 'org.junit-pioneer:junit-pioneer:2.0.1'
@@ -39,29 +49,31 @@ group 'theodolite'
 version '0.10.0-SNAPSHOT'
 
 java {
-    sourceCompatibility = JavaVersion.VERSION_11
-    targetCompatibility = JavaVersion.VERSION_11
+    sourceCompatibility = JavaVersion.VERSION_17
+    targetCompatibility = JavaVersion.VERSION_17
 }
 
 allOpen {
-    annotation("javax.ws.rs.Path")
-    annotation("javax.enterprise.context.ApplicationScoped")
+    annotation("jakarta.ws.rs.Path")
+    annotation("jakarta.enterprise.context.ApplicationScoped")
     annotation("io.quarkus.test.junit.QuarkusTest")
 }
 
 compileKotlin {
-    kotlinOptions.jvmTarget = JavaVersion.VERSION_11
+    kotlinOptions.jvmTarget = JavaVersion.VERSION_17
     kotlinOptions.javaParameters = true
 }
 
 compileTestKotlin {
-    kotlinOptions.jvmTarget = JavaVersion.VERSION_11
+    kotlinOptions.jvmTarget = JavaVersion.VERSION_17
 }
 
 test {
+    // systemProperty "java.util.logging.manager", "org.jboss.logmanager.LogManager"
+
     // Required because of https://github.com/quarkusio/quarkus/issues/18973
-    minHeapSize = "256m"
-    maxHeapSize = "1024m"
+    minHeapSize = "512m"
+    maxHeapSize = "2048m"
 
     // Temporary fix environment variable test
     jvmArgs = [
diff --git a/theodolite/gradle.properties b/theodolite/gradle.properties
index a7c5a39013639072e1ef47f9226b95b513d678d7..008ce78ac0ab357e1d6d2663be608420d5580585 100644
--- a/theodolite/gradle.properties
+++ b/theodolite/gradle.properties
@@ -1,8 +1,6 @@
 #Gradle properties
 quarkusPluginId=io.quarkus
-quarkusPluginVersion=2.7.4.Final
+quarkusPluginVersion=3.2.2.Final
 quarkusPlatformGroupId=io.quarkus.platform
 quarkusPlatformArtifactId=quarkus-bom
-quarkusPlatformVersion=2.7.4.Final
-
-#org.gradle.logging.level=INFO
\ No newline at end of file
+quarkusPlatformVersion=3.2.2.Final
diff --git a/theodolite/settings.gradle b/theodolite/settings.gradle
index a726b4afa4cfdc7433dbd408808ab0fd6a766d6a..bfa19d83d8ae401b27b659cf97c1126d850d2154 100644
--- a/theodolite/settings.gradle
+++ b/theodolite/settings.gradle
@@ -1,8 +1,8 @@
 pluginManagement {
     repositories {
-        mavenLocal()
         mavenCentral()
         gradlePluginPortal()
+        mavenLocal()
     }
     plugins {
         id "${quarkusPluginId}" version "${quarkusPluginVersion}"
diff --git a/theodolite/src/main/docker/Dockerfile.jvm b/theodolite/src/main/docker/Dockerfile.jvm
index e33d7c379a4336610c16d59b9d3315a1e8abad2b..3e95ceb48000a129f250477d4db37f4ad6272f0a 100644
--- a/theodolite/src/main/docker/Dockerfile.jvm
+++ b/theodolite/src/main/docker/Dockerfile.jvm
@@ -14,19 +14,73 @@
 # 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 5005
+# you will have to expose the debug port (default 5005 being the default) like this :  EXPOSE 8080 5005.
+# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005
+# when running the container
 #
 # Then run the container using :
 #
 # docker run -i --rm -p 8080:8080 quarkus/theodolite-jvm
 #
+# This image uses the `run-java.sh` script to run the application.
+# This scripts computes the command line to execute your Java application, and
+# includes memory/GC tuning.
+# You can configure the behavior using the following environment properties:
+# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class")
+# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options
+#   in JAVA_OPTS (example: "-Dsome.property=foo")
+# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is
+#   used to calculate a default maximal heap memory based on a containers restriction.
+#   If used in a container without any memory constraints for the container then this
+#   option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio
+#   of the container available memory as set here. The default is `50` which means 50%
+#   of the available memory is used as an upper boundary. You can skip this mechanism by
+#   setting this value to `0` in which case no `-Xmx` option is added.
+# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This
+#   is used to calculate a default initial heap memory based on the maximum heap memory.
+#   If used in a container without any memory constraints for the container then this
+#   option has no effect. If there is a memory constraint then `-Xms` is set to a ratio
+#   of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx`
+#   is used as the initial heap size. You can skip this mechanism by setting this value
+#   to `0` in which case no `-Xms` option is added (example: "25")
+# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS.
+#   This is used to calculate the maximum value of the initial heap memory. If used in
+#   a container without any memory constraints for the container then this option has
+#   no effect. If there is a memory constraint then `-Xms` is limited to the value set
+#   here. The default is 4096MB which means the calculated value of `-Xms` never will
+#   be greater than 4096MB. The value of this variable is expressed in MB (example: "4096")
+# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output
+#   when things are happening. This option, if set to true, will set
+#  `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true").
+# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example:
+#    true").
+# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787").
+# - CONTAINER_CORE_LIMIT: A calculated core limit as described in
+#   https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2")
+# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024").
+# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion.
+#   (example: "20")
+# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking.
+#   (example: "40")
+# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection.
+#   (example: "4")
+# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus
+#   previous GC times. (example: "90")
+# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20")
+# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100")
+# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should
+#   contain the necessary JRE command-line options to specify the required GC, which
+#   will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC).
+# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080")
+# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080")
+# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be
+#   accessed directly. (example: "foo.example.com,bar.example.com")
+#
 ###
-FROM registry.access.redhat.com/ubi8/openjdk-11-runtime:1.10
+FROM registry.access.redhat.com/ubi8/openjdk-17:1.16
 
-ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
+ENV LANGUAGE='en_US:en'
 
-# 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=185 build/quarkus-app/lib/ /deployments/lib/
@@ -36,6 +90,8 @@ COPY --chown=185 build/quarkus-app/quarkus/ /deployments/quarkus/
 
 EXPOSE 8080
 USER 185
+ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
+ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
 
-ENTRYPOINT [ "java", "-jar", "/deployments/quarkus-run.jar" ]
+ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ]
 
diff --git a/theodolite/src/main/docker/Dockerfile.legacy-jar b/theodolite/src/main/docker/Dockerfile.legacy-jar
index aa5908c4ed42f005fa67c17fd2c3b3e00978228a..97d0b53b23d8252f62148060100df0c28c9a7739 100644
--- a/theodolite/src/main/docker/Dockerfile.legacy-jar
+++ b/theodolite/src/main/docker/Dockerfile.legacy-jar
@@ -14,24 +14,80 @@
 # 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 5005
+# you will have to expose the debug port (default 5005 being the default) like this :  EXPOSE 8080 5005.
+# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005
+# when running the container
 #
 # Then run the container using :
 #
 # docker run -i --rm -p 8080:8080 quarkus/theodolite-legacy-jar
 #
+# This image uses the `run-java.sh` script to run the application.
+# This scripts computes the command line to execute your Java application, and
+# includes memory/GC tuning.
+# You can configure the behavior using the following environment properties:
+# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class")
+# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options
+#   in JAVA_OPTS (example: "-Dsome.property=foo")
+# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is
+#   used to calculate a default maximal heap memory based on a containers restriction.
+#   If used in a container without any memory constraints for the container then this
+#   option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio
+#   of the container available memory as set here. The default is `50` which means 50%
+#   of the available memory is used as an upper boundary. You can skip this mechanism by
+#   setting this value to `0` in which case no `-Xmx` option is added.
+# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This
+#   is used to calculate a default initial heap memory based on the maximum heap memory.
+#   If used in a container without any memory constraints for the container then this
+#   option has no effect. If there is a memory constraint then `-Xms` is set to a ratio
+#   of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx`
+#   is used as the initial heap size. You can skip this mechanism by setting this value
+#   to `0` in which case no `-Xms` option is added (example: "25")
+# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS.
+#   This is used to calculate the maximum value of the initial heap memory. If used in
+#   a container without any memory constraints for the container then this option has
+#   no effect. If there is a memory constraint then `-Xms` is limited to the value set
+#   here. The default is 4096MB which means the calculated value of `-Xms` never will
+#   be greater than 4096MB. The value of this variable is expressed in MB (example: "4096")
+# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output
+#   when things are happening. This option, if set to true, will set
+#  `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true").
+# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example:
+#    true").
+# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787").
+# - CONTAINER_CORE_LIMIT: A calculated core limit as described in
+#   https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2")
+# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024").
+# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion.
+#   (example: "20")
+# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking.
+#   (example: "40")
+# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection.
+#   (example: "4")
+# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus
+#   previous GC times. (example: "90")
+# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20")
+# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100")
+# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should
+#   contain the necessary JRE command-line options to specify the required GC, which
+#   will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC).
+# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080")
+# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080")
+# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be
+#   accessed directly. (example: "foo.example.com,bar.example.com")
+#
 ###
-FROM registry.access.redhat.com/ubi8/openjdk-11-runtime:1.10
+FROM registry.access.redhat.com/ubi8/openjdk-17:1.16
 
-ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
+ENV LANGUAGE='en_US:en'
 
-# 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/quarkus-run.jar
 
 EXPOSE 8080
 USER 185
+ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
+ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
 
-ENTRYPOINT [ "java", "-jar", "/deployments/quarkus-run.jar" ]
+ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ]
diff --git a/theodolite/src/main/docker/Dockerfile.native b/theodolite/src/main/docker/Dockerfile.native
index 34ccd6622bf2fba6f9707989fffd9bb6390a4a8b..a81683b0436b2dbe85fae64f9e7031626f1568e9 100644
--- a/theodolite/src/main/docker/Dockerfile.native
+++ b/theodolite/src/main/docker/Dockerfile.native
@@ -1,5 +1,5 @@
 ####
-# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode
+# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode.
 #
 # Before building the container image run:
 #
@@ -14,7 +14,7 @@
 # docker run -i --rm -p 8080:8080 quarkus/theodolite
 #
 ###
-FROM quay.io/quarkus/quarkus-micro-image:1.0
+FROM registry.access.redhat.com/ubi8/ubi-minimal:8.8
 WORKDIR /work/
 RUN chown 1001 /work \
     && chmod "g+rwX" /work \
@@ -24,4 +24,4 @@ COPY --chown=1001:root build/*-runner /work/application
 EXPOSE 8080
 USER 1001
 
-CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
+ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"]
diff --git a/theodolite/src/main/docker/Dockerfile.native-micro b/theodolite/src/main/docker/Dockerfile.native-micro
new file mode 100644
index 0000000000000000000000000000000000000000..ea4cf374ffc199525308113f38f3e74cc5d864cb
--- /dev/null
+++ b/theodolite/src/main/docker/Dockerfile.native-micro
@@ -0,0 +1,30 @@
+####
+# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode.
+# It uses a micro base image, tuned for Quarkus native executables.
+# It reduces the size of the resulting container image.
+# Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image.
+#
+# 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-micro -t quarkus/theodolite .
+#
+# Then run the container using:
+#
+# docker run -i --rm -p 8080:8080 quarkus/theodolite
+#
+###
+FROM quay.io/quarkus/quarkus-micro-image:2.0
+WORKDIR /work/
+RUN chown 1001 /work \
+    && chmod "g+rwX" /work \
+    && chown 1001:root /work
+COPY --chown=1001:root build/*-runner /work/application
+
+EXPOSE 8080
+USER 1001
+
+ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"]
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Action.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Action.kt
index bdabb719672abf2975fdf8a0ad59868bbc6c1edf..486bbb88903b9222ea4864fdfaf115d55de12851 100644
--- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Action.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Action.kt
@@ -3,6 +3,7 @@ package rocks.theodolite.kubernetes
 import com.fasterxml.jackson.annotation.JsonInclude
 import com.fasterxml.jackson.annotation.JsonProperty
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize
+import io.fabric8.kubernetes.client.KubernetesClient
 import io.fabric8.kubernetes.client.NamespacedKubernetesClient
 import io.quarkus.runtime.annotations.RegisterForReflection
 
@@ -18,11 +19,11 @@ class Action {
     @JsonInclude(JsonInclude.Include.NON_NULL)
     var deleteCommand: DeleteCommand? = null
 
-    fun exec(client: NamespacedKubernetesClient) {
+    fun exec(client: KubernetesClient) {
         return if (execCommand != null) {
-            execCommand?.exec(client= client) !!
+            execCommand?.exec(client) !!
         } else if (deleteCommand != null) {
-            deleteCommand?.exec(client= client ) !!
+            deleteCommand?.exec(client) !!
         } else {
             throw DeploymentFailedException("Could not execute action. The action type must either be 'exec' or 'delete'.")
         }
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ActionCommand.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ActionCommand.kt
index eefacbea9268f44969fd88d7650d5ddc5e00fb8e..e6dac50627652731fc7c00d127283b052d043a52 100644
--- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ActionCommand.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ActionCommand.kt
@@ -1,33 +1,26 @@
 package rocks.theodolite.kubernetes
 
-import io.fabric8.kubernetes.api.model.Status
+import io.fabric8.kubernetes.client.KubernetesClient
 import io.fabric8.kubernetes.client.KubernetesClientException
-import io.fabric8.kubernetes.client.NamespacedKubernetesClient
-import io.fabric8.kubernetes.client.dsl.ExecListener
 import io.fabric8.kubernetes.client.dsl.ExecWatch
-import io.fabric8.kubernetes.client.utils.Serialization
 import mu.KotlinLogging
 import java.io.ByteArrayOutputStream
 import java.time.Duration
-import java.util.concurrent.CountDownLatch
 import java.util.concurrent.TimeUnit
 
 
 private val logger = KotlinLogging.logger {}
 
-class ActionCommand(val client: NamespacedKubernetesClient) {
-    var out: ByteArrayOutputStream = ByteArrayOutputStream()
-    var error: ByteArrayOutputStream = ByteArrayOutputStream()
-    var errChannelStream: ByteArrayOutputStream = ByteArrayOutputStream()
-    private val execLatch = CountDownLatch(1)
+class ActionCommand(val client: KubernetesClient) {
 
     /**
      * Executes an action command.
      *
      * @param matchLabels matchLabels specifies on which pod the command should be executed. For this, the principle
      * `of any` of is used and the command is called on one of the possible pods.
-     * @param container (Optional) The container to run the command. Is optional iff exactly one container exist.
      * @param command The command to be executed.
+     * @param timeout (Optional) Timeout for running the command.
+     * @param container (Optional) The container to run the command. Is optional iff exactly one container exist.
      * @return the exit code of this executed command
      */
     fun exec(
@@ -37,69 +30,26 @@ class ActionCommand(val client: NamespacedKubernetesClient) {
         container: String = ""
     ): Int {
         try {
-            val execWatch: ExecWatch = if (container.isNotEmpty()) {
-                client.pods()
-                    .inNamespace(client.namespace)
-                    .withName(getPodName(matchLabels, 3))
-                    .inContainer(container)
-
-            } else {
-                client.pods()
-                    .inNamespace(client.namespace)
-                    .withName(getPodName(matchLabels, 3))
-            }
-                .writingOutput(out)
-                .writingError(error)
-                .writingErrorChannel(errChannelStream)
-                .usingListener(ActionCommandListener(execLatch))
+            val outStream = ByteArrayOutputStream()
+            val errorStream = ByteArrayOutputStream()
+            val execWatch: ExecWatch = client.pods()
+                .inNamespace(client.namespace)
+                .withName(awaitPodName(matchLabels, 3))
+                .let { if (container.isNotEmpty()) it.inContainer(container) else it }
+                .writingOutput(outStream)
+                .writingError(errorStream)
                 .exec(*command)
-
-            val latchTerminationStatus = execLatch.await(timeout, TimeUnit.SECONDS)
-            if (!latchTerminationStatus) {
-                throw ActionCommandFailedException("Timeout while running action command")
-            }
+            val exitCode = execWatch.exitCode().get(timeout, TimeUnit.SECONDS)
             execWatch.close()
-        } catch (e: Exception) {
-            when (e) {
-                is InterruptedException -> {
-                    Thread.currentThread().interrupt()
-                    throw ActionCommandFailedException("Interrupted while waiting for the exec", e)
-                }
-                is KubernetesClientException -> {
-                    throw ActionCommandFailedException("Error while executing command", e)
-                }
-                else -> {
-                    throw e
-                }
-            }
+            logger.debug { "Execution Output Stream is \n $outStream" }
+            logger.debug { "Execution Error Stream is \n $errorStream" }
+            return exitCode
+        } catch (e: InterruptedException) {
+            Thread.currentThread().interrupt()
+            throw ActionCommandFailedException("Interrupted while waiting for the exec", e)
+        } catch (e: KubernetesClientException) {
+            throw ActionCommandFailedException("Error while executing command", e)
         }
-        logger.debug { "Execution Output Stream is \n $out" }
-        logger.debug { "Execution Error Stream is \n $error" }
-        logger.debug { "Execution ErrorChannel is: \n $errChannelStream" }
-        return getExitCode(errChannelStream)
-    }
-
-    private fun getExitCode(errChannelStream: ByteArrayOutputStream): Int {
-        val status: Status?
-        try {
-            status = Serialization.unmarshal(errChannelStream.toString(), Status::class.java)
-        } catch (e: Exception) {
-            throw ActionCommandFailedException("Could not determine the exit code, no information given")
-        }
-
-        if (status == null) {
-            throw ActionCommandFailedException("Could not determine the exit code, no information given")
-        }
-
-        return if (status.status.equals("Success")) {
-            0
-        } else status.details.causes.stream()
-            .filter { it.reason.equals("ExitCode") }
-            .map { it.message }
-            .findFirst()
-            .orElseThrow {
-                ActionCommandFailedException("Status is not SUCCESS but contains no exit code - Status: $status")
-            }.toInt()
     }
 
     /**
@@ -110,9 +60,8 @@ class ActionCommand(val client: NamespacedKubernetesClient) {
      * it can take a while until the status is ready and the pod can be selected.
      * @return the name of the pod or throws [ActionCommandFailedException]
      */
-    fun getPodName(matchLabels: Map<String, String>, tries: Int): String {
+    fun awaitPodName(matchLabels: Map<String, String>, tries: Int): String {
         for (i in 1..tries) {
-
             try {
                 return getPodName(matchLabels)
             } catch (e: Exception) {
@@ -141,16 +90,4 @@ class ActionCommand(val client: NamespacedKubernetesClient) {
         }
     }
 
-    private class ActionCommandListener(val execLatch: CountDownLatch) : ExecListener {
-
-        override fun onFailure(throwable: Throwable, response: ExecListener.Response) {
-            execLatch.countDown()
-            throw ActionCommandFailedException("Some error encountered while executing action, caused ${throwable.message})")
-        }
-
-        override fun onClose(code: Int, reason: String) {
-            execLatch.countDown()
-        }
-    }
-
 }
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ConfigMapResourceSet.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ConfigMapResourceSet.kt
index 43c478b983d879135b00e6208df8bb36b7978c8f..15a2f6d32a54faa51662a4288f8f7cf079c3d77b 100644
--- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ConfigMapResourceSet.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ConfigMapResourceSet.kt
@@ -41,7 +41,7 @@ class ConfigMapResourceSet : ResourceSet, KubernetesResource {
                 .map {
                     Pair(
                         it.key, // filename
-                        client.resource(it.value).get()
+                        client.resource(it.value).item()
                     )
                 }
         } catch (e: IllegalArgumentException) {
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/DeleteCommand.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/DeleteCommand.kt
index ef4409e5bdebfa8b232d5ed1080e93571cbaa618..502fb9b23558564a62bc2a0093fcfc25ede04823 100644
--- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/DeleteCommand.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/DeleteCommand.kt
@@ -2,8 +2,8 @@ package rocks.theodolite.kubernetes
 
 import com.fasterxml.jackson.annotation.JsonInclude
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize
+import io.fabric8.kubernetes.client.KubernetesClient
 import io.fabric8.kubernetes.client.KubernetesClientException
-import io.fabric8.kubernetes.client.NamespacedKubernetesClient
 import io.quarkus.runtime.annotations.RegisterForReflection
 import mu.KotlinLogging
 
@@ -16,7 +16,7 @@ class DeleteCommand {
 
     lateinit var selector: DeleteActionSelector
 
-    fun exec(client: NamespacedKubernetesClient) {
+    fun exec(client: KubernetesClient) {
         logger.info { "Deleting all resources with apiVersion ${selector.apiVersion} and Kind ${selector.kind} matching regular expression ${selector.nameRegex}" }
         val regExp = selector.nameRegex.toRegex()
         val k8sManager = K8sManager(client)
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExecCommand.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExecCommand.kt
index b8ce10efcd3e4fb5ea552aa7f922fd81c5c13656..1691b414695c3eaaa207ff9c70788bf4e7801b71 100644
--- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExecCommand.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExecCommand.kt
@@ -2,7 +2,7 @@ package rocks.theodolite.kubernetes
 
 import com.fasterxml.jackson.annotation.JsonInclude
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize
-import io.fabric8.kubernetes.client.NamespacedKubernetesClient
+import io.fabric8.kubernetes.client.KubernetesClient
 import io.quarkus.runtime.annotations.RegisterForReflection
 
 @JsonDeserialize
@@ -12,7 +12,7 @@ class ExecCommand {
     lateinit var selector: ExecActionSelector
     lateinit var command: Array<String>
     var timeoutSeconds: Long = Configuration.TIMEOUT_SECONDS
-    fun exec(client: NamespacedKubernetesClient) {
+    fun exec(client: KubernetesClient) {
         val exitCode = ActionCommand(client = client)
             .exec(
                 matchLabels = selector.pod.matchLabels,
@@ -20,7 +20,7 @@ class ExecCommand {
                 timeout = timeoutSeconds,
                 command = command
             )
-        if (exitCode != 0){
+        if (exitCode != 0) {
             throw ActionCommandFailedException("Error while executing action, finished with exit code $exitCode")
         }
     }
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExperimentRunnerImpl.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExperimentRunnerImpl.kt
index 3e964a1e0d5a9e512a9eefa16b90acf588a537eb..707ef1b8f8bb81eb3823c78b67d30478a4f7b76c 100644
--- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExperimentRunnerImpl.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExperimentRunnerImpl.kt
@@ -60,8 +60,7 @@ class ExperimentRunnerImpl(
                     .analyze(
                         load = load,
                         resource = resource,
-                        executionIntervals = executionIntervals,
-                        metric = this.results.metric
+                        executionIntervals = executionIntervals
                     )
             }
 
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/FileSystemResourceSet.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/FileSystemResourceSet.kt
index 6f430d54cfe9898324b7b9c33df6646b9e6d06ff..6a0b0203f1fcc0f349d495d7c58392c2c9479821 100644
--- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/FileSystemResourceSet.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/FileSystemResourceSet.kt
@@ -45,7 +45,7 @@ class FileSystemResourceSet: ResourceSet, KubernetesResource {
                 val text = BufferedReader(InputStreamReader(it, StandardCharsets.UTF_8))
                         .lines()
                         .collect(Collectors.joining("\n"))
-                val k8sResource = client.resource(text).get()
+                val k8sResource = client.resource(text).item()
                 Pair(resource.last().toString(), k8sResource)
             }
         } catch (e: FileNotFoundException){
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/K8sManager.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/K8sManager.kt
index 7856451edf4c31d668288f618fcee46b7246a619..0b34f4564829307df27f6910c5a7753f362b3dcf 100644
--- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/K8sManager.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/K8sManager.kt
@@ -3,6 +3,7 @@ package rocks.theodolite.kubernetes
 import io.fabric8.kubernetes.api.model.HasMetadata
 import io.fabric8.kubernetes.api.model.apps.Deployment
 import io.fabric8.kubernetes.api.model.apps.StatefulSet
+import io.fabric8.kubernetes.client.KubernetesClient
 import io.fabric8.kubernetes.client.NamespacedKubernetesClient
 import mu.KotlinLogging
 
@@ -13,7 +14,7 @@ private val logger = KotlinLogging.logger {}
  * Supports: Deployments, Services, ConfigMaps, StatefulSets, and CustomResources.
  * @param client KubernetesClient used to deploy or remove.
  */
-class K8sManager(private val client: NamespacedKubernetesClient) {
+class K8sManager(private val client: KubernetesClient) {
 
     /**
      * Deploys different k8s resources using the client.
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ResourceByLabelHandler.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ResourceByLabelHandler.kt
index 6fdf80e3c1fcace633adc135123fb95ab49d1fc4..ab42a67dd795c3fbd7469d590d6e547647088daa 100644
--- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ResourceByLabelHandler.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ResourceByLabelHandler.kt
@@ -1,5 +1,6 @@
 package rocks.theodolite.kubernetes
 
+import io.fabric8.kubernetes.client.KubernetesClient
 import io.fabric8.kubernetes.client.NamespacedKubernetesClient
 import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext
 import mu.KotlinLogging
@@ -10,7 +11,7 @@ private val logger = KotlinLogging.logger {}
  * The ResourceByLabelHandler provides basic functions to manage Kubernetes resources through their labels.
  * @param client NamespacedKubernetesClient used for the deletion.
  */
-class ResourceByLabelHandler(private val client: NamespacedKubernetesClient) {
+class ResourceByLabelHandler(private val client: KubernetesClient) {
 
     /**
      * Deletes all pods with the selected label.
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/AbstractStateHandler.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/AbstractStateHandler.kt
index 96593914cf07c427c924a1631a00f76dc3649ed3..775669bec3f682661416106731dc2563c2ba6595 100644
--- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/AbstractStateHandler.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/AbstractStateHandler.kt
@@ -38,12 +38,8 @@ abstract class AbstractStateHandler<S : HasMetadata>(
     }
 
     @Synchronized
-    fun getState(resourceName: String, f: (S) -> String?): String? {
-        return this.crdClient
-            .list().items
-            .filter { it.metadata.name == resourceName }
-            .map { customResource -> f(customResource) }
-            .firstOrNull()
+    fun getState(resourceName: String, stateAccessor: (S) -> String?): String? {
+        return this.crdClient.withName(resourceName)?.get()?.let(stateAccessor)
     }
 
     @Synchronized
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateHandler.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateHandler.kt
index 9a272b43f911bf523adf7c64c5ab34793b7a7dc5..834a8ddaaafbfd7376dd8f8ecac75ab9332d11c3 100644
--- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateHandler.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateHandler.kt
@@ -3,6 +3,7 @@ package rocks.theodolite.kubernetes.operator
 import io.fabric8.kubernetes.client.NamespacedKubernetesClient
 import rocks.theodolite.kubernetes.model.crd.BenchmarkCRD
 import rocks.theodolite.kubernetes.model.crd.BenchmarkState
+import rocks.theodolite.kubernetes.model.crd.ExecutionCRD
 import rocks.theodolite.kubernetes.model.crd.ExecutionState
 
 class BenchmarkStateHandler(val client: NamespacedKubernetesClient) :
@@ -11,15 +12,15 @@ class BenchmarkStateHandler(val client: NamespacedKubernetesClient) :
         crd = BenchmarkCRD::class.java
     ) {
 
-    private fun getBenchmarkResourceState() = { cr: BenchmarkCRD -> cr.status.resourceSetsState.value }
+    private val benchmarkResourceStateAccessor = { cr: BenchmarkCRD -> cr.status.resourceSetsState.value }
 
     fun setResourceSetState(resourceName: String, status: BenchmarkState): Boolean {
         setState(resourceName) { cr -> cr.status.resourceSetsState = status; cr }
-        return blockUntilStateIsSet(resourceName, status.value, getBenchmarkResourceState())
+        return blockUntilStateIsSet(resourceName, status.value, benchmarkResourceStateAccessor)
     }
 
     fun getResourceSetState(resourceName: String): ExecutionState {
-        val status = this.getState(resourceName, getBenchmarkResourceState())
+        val status = this.getState(resourceName, benchmarkResourceStateAccessor)
         return if (status.isNullOrBlank()) {
             ExecutionState.NO_STATE
         } else {
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/ExecutionStateHandler.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/ExecutionStateHandler.kt
index cb3dca8a6389e0db4c064e0d65929daab5cebc90..2ef38a1d74c358b1c9ffa44d2d574aedf91a62e0 100644
--- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/ExecutionStateHandler.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/ExecutionStateHandler.kt
@@ -16,15 +16,15 @@ class ExecutionStateHandler(val client: NamespacedKubernetesClient) :
 
     private var runExecutionDurationTimer: AtomicBoolean = AtomicBoolean(false)
 
-    private fun getExecutionLambda() = { cr: ExecutionCRD -> cr.status.executionState.value }
+    private val executionStateAccessor = { cr: ExecutionCRD -> cr.status.executionState.value }
 
     fun setExecutionState(resourceName: String, status: ExecutionState): Boolean {
         super.setState(resourceName) { cr -> cr.status.executionState = status; cr }
-        return blockUntilStateIsSet(resourceName, status.value, getExecutionLambda())
+        return blockUntilStateIsSet(resourceName, status.value, executionStateAccessor)
     }
 
     fun getExecutionState(resourceName: String): ExecutionState {
-        val statusString = this.getState(resourceName, getExecutionLambda())
+        val statusString = this.getState(resourceName, executionStateAccessor)
         return ExecutionState.values().first { it.value == statusString }
     }
 
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/TheodoliteOperator.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/TheodoliteOperator.kt
index e4677018563a078fc2ec796ed71d4b886a6dea00..ecc0cc3f769c74ff29b852842210c192b525e86b 100644
--- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/TheodoliteOperator.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/TheodoliteOperator.kt
@@ -45,17 +45,6 @@ class TheodoliteOperator(private val client: NamespacedKubernetesClient) {
     private fun startOperator() {
         logger.info { "Becoming the leading operator. Use namespace '${this.client.namespace}'." }
         client.use {
-            KubernetesDeserializer.registerCustomKind(
-                "$GROUP/$API_VERSION",
-                EXECUTION_SINGULAR,
-                ExecutionCRD::class.java
-            )
-
-            KubernetesDeserializer.registerCustomKind(
-                "$GROUP/$API_VERSION",
-                BENCHMARK_SINGULAR,
-                BenchmarkCRD::class.java
-            )
 
             ClusterSetup(
                 executionCRDClient = getExecutionClient(),
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ConfigMapYamlPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ConfigMapYamlPatcher.kt
index 28b2d55d49206df935b4a5303b045e2a69bbd1ac..d51ce7299b703c7258d450170c8b59d351750498 100644
--- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ConfigMapYamlPatcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ConfigMapYamlPatcher.kt
@@ -27,7 +27,7 @@ class ConfigMapYamlPatcher(
             val parser = Yaml(dumperOptions)
 
             // Change value
-            val yaml = parser.loadAs(yamlFile, LinkedHashMap<String, Any>()::class.java)
+            val yaml: MutableMap<String, Any> = parser.loadAs(yamlFile, LinkedHashMap<String, Any>()::class.java)
             yaml[variableName] = value.toLongOrNull() ?: value.toDoubleOrNull() ?: value.toBooleanStrictOrNull() ?: value
 
             // Convert back to String and set in Kubernetes resource
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/GenericResourcePatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/GenericResourcePatcher.kt
index d74c8a22d0b0f06d5f80c299decdb1f0160cd5b2..097c8a03d25a6c7763c730f39fb28f41e469eb6a 100644
--- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/GenericResourcePatcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/GenericResourcePatcher.kt
@@ -22,7 +22,7 @@ class GenericResourcePatcher(val path: List<Any>, val type: Type = Type.STRING)
             var current: Any? = resource.additionalProperties
             for (segment in path.dropLast(1)) {
                 current = if (segment is Int && current is MutableList<*> && current.size > segment) {
-                    current.toTypedArray()[segment]
+                    current[segment]
                 } else if (segment is String && current is Map<*, *>) {
                     current[segment]
                 } else {
@@ -33,8 +33,10 @@ class GenericResourcePatcher(val path: List<Any>, val type: Type = Type.STRING)
             if (segment == null) {
                 throw IllegalArgumentException("Path must not be empty")
             } else if (segment is Int && current is MutableList<*> && current.size > segment) {
+                @Suppress("UNCHECKED_CAST")
                 (current as MutableList<Any?>)[segment] = castedValue
             } else if (segment is String && current is Map<*, *>) {
+                @Suppress("UNCHECKED_CAST")
                 (current as MutableMap<String, Any>)[segment] = castedValue
             } else {
                 throw IllegalArgumentException("Cannot set value for path")
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/AnalysisExecutor.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/AnalysisExecutor.kt
index b7cd32d735fe2cdc0888df4a563499ca76b60886..a4a775bad2a551a55dbe4e442aee395ad96c337b 100644
--- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/AnalysisExecutor.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/AnalysisExecutor.kt
@@ -31,7 +31,7 @@ class AnalysisExecutor(
      *  @param executionIntervals list of start and end points of experiments
      *  @return true if the experiment succeeded.
      */
-    fun analyze(load: Int, resource: Int, executionIntervals: List<Pair<Instant, Instant>>, metric: Metric): Boolean {
+    fun analyze(load: Int, resource: Int, executionIntervals: List<Pair<Instant, Instant>>): Boolean {
         var repetitionCounter = 1
 
         try {
@@ -60,8 +60,7 @@ class AnalysisExecutor(
                 sloType = slo.sloType,
                 properties = slo.properties,
                 load = load,
-                resources = resource,
-                metric = metric
+                resources = resource
             )
 
             return sloChecker.evaluate(prometheusData)
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloCheckerFactory.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloCheckerFactory.kt
index 2c4caea44cd0d6b9534c2ed69f1db5df721408ad..32aa2f5cf298121be2c1e2791ae4cf6ad50fa73d 100644
--- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloCheckerFactory.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloCheckerFactory.kt
@@ -45,8 +45,7 @@ class SloCheckerFactory {
         sloType: String,
         properties: Map<String, String>,
         load: Int,
-        resources: Int,
-        metric: Metric
+        resources: Int
     ): SloChecker =
         when (SloTypes.from(sloType)) {
             SloTypes.GENERIC -> ExternalSloChecker(
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloConfigHandler.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloConfigHandler.kt
index 404255496f57f7e25259268db6d04a8c81139f75..7a24bfca3a992d98451ab19d17d9ee246b2afa5a 100644
--- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloConfigHandler.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloConfigHandler.kt
@@ -2,7 +2,7 @@ package rocks.theodolite.kubernetes.slo
 
 import rocks.theodolite.kubernetes.model.KubernetesBenchmark.Slo
 import rocks.theodolite.kubernetes.patcher.InvalidPatcherConfigurationException
-import javax.enterprise.context.ApplicationScoped
+import jakarta.enterprise.context.ApplicationScoped
 
 private const val DEFAULT_CONSUMER_LAG_METRIC_BASE = "kafka_consumergroup_lag"
 private const val DEFAULT_CONSUMER_LAG_QUERY = "sum by(consumergroup) (kafka_consumergroup_lag >= 0)"
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/util/Parser.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/util/Parser.kt
index 65cd6a39303d3f0f0814c7197bbe15b4919be5d7..53c4ac20cb6d7d002423683847f49b7e303d4b28 100644
--- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/util/Parser.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/util/Parser.kt
@@ -9,8 +9,8 @@ interface Parser {
      * Parse a file.
      *
      * @param path The path of the file
-     * @param E The class of the type to parse
+     * @param clazz The class of the type to parse
      * @param T The type to parse
      */
-    fun <T> parse(path: String, E: Class<T>): T?
+    fun <T> parse(path: String, clazz: Class<T>): T?
 }
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/util/YamlParserFromFile.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/util/YamlParserFromFile.kt
index fb5b1e419aa2f6fcc369cf14e5104f7efde48d3d..125ac1def3f0635eee0b2c1a6709009a6e5006ea 100644
--- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/util/YamlParserFromFile.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/util/YamlParserFromFile.kt
@@ -1,5 +1,6 @@
 package rocks.theodolite.kubernetes.util
 
+import org.yaml.snakeyaml.LoaderOptions
 import org.yaml.snakeyaml.Yaml
 import org.yaml.snakeyaml.constructor.Constructor
 import java.io.File
@@ -13,7 +14,7 @@ import java.io.InputStream
 class YamlParserFromFile : Parser {
     override fun <T> parse(path: String, clazz: Class<T>): T? {
         val input: InputStream = FileInputStream(File(path))
-        val parser = Yaml(Constructor(clazz))
+        val parser = Yaml(Constructor(clazz, LoaderOptions()))
         return parser.loadAs(input, clazz)
     }
 }
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ActionCommandTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ActionCommandTest.kt
index 008bc302f1ba9a246b7bd898aec712f305c5b288..6e7a5407a7113d2d88cf4fab4978f1d92c081aec 100644
--- a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ActionCommandTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ActionCommandTest.kt
@@ -1,127 +1,139 @@
 package rocks.theodolite.kubernetes
 
-import io.fabric8.kubernetes.api.model.Pod
-import io.fabric8.kubernetes.api.model.PodBuilder
-import io.fabric8.kubernetes.api.model.PodListBuilder
-import io.fabric8.kubernetes.client.server.mock.KubernetesServer
-import io.fabric8.kubernetes.client.utils.Utils
+import io.fabric8.kubernetes.api.model.*
+import io.fabric8.kubernetes.client.ConfigBuilder
+import io.fabric8.kubernetes.client.KubernetesClient
+import io.fabric8.kubernetes.client.KubernetesClientBuilder
+import io.fabric8.kubernetes.client.http.*
+import io.fabric8.kubernetes.client.utils.Serialization
 import io.quarkus.test.junit.QuarkusTest
 import org.junit.jupiter.api.*
 import org.junit.jupiter.api.Assertions.assertEquals
-import rocks.theodolite.kubernetes.operator.TheodoliteController
-import rocks.theodolite.kubernetes.operator.TheodoliteOperator
+import org.junit.jupiter.api.Assertions.assertTrue
+import org.mockito.ArgumentMatchers
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import java.nio.ByteBuffer
+import java.nio.charset.StandardCharsets
+import java.util.concurrent.CompletableFuture
 
 
 @QuarkusTest
 class ActionCommandTest {
-    private val server = KubernetesServer(false, false)
-    lateinit var controller: TheodoliteController
+
+    private lateinit var factory: TestStandardHttpClientFactory
+    private lateinit var client: KubernetesClient
+    private lateinit var httpClient: TestStandardHttpClient
 
     @BeforeEach
     fun setUp() {
-        server.before()
-        val operator = TheodoliteOperator(server.client)
-        this.controller = operator.getController(
-            executionStateHandler = operator.getExecutionStateHandler(),
-            benchmarkStateChecker = operator.getBenchmarkStateChecker()
-        )
-
-        val pod: Pod = PodBuilder().withNewMetadata()
-            .withName("pod1")
-            .withResourceVersion("1")
-            .withLabels<String, String>(mapOf("app" to "pod"))
-            .withNamespace("test").and()
-            .build()
-
-        val ready: Pod = createReadyFrom(pod, "True")
-
-        val podList = PodListBuilder().build()
-        podList.items.add(0, ready)
-
-        server
-            .expect()
-            .withPath("/api/v1/namespaces/test/pods?labelSelector=${Utils.toUrlEncoded("app=pod")}")
-            .andReturn(200, podList)
-            .always()
-
-        server
-            .expect()
-            .get()
-            .withPath("/api/v1/namespaces/test/pods/pod1")
-            .andReturn(200, ready)
-            .always()
-
-        server
-            .expect()
-            .withPath("/api/v1/namespaces/test/pods/pod1/exec?command=ls&stdout=true&stderr=true")
-            .andUpgradeToWebSocket()
-            .open(ErrorChannelMessage("{\"metadata\":{},\"status\":\"Success\"}\n"))
-            .done()
-            .always()
-
-        server
-            .expect()
-            .withPath("/api/v1/namespaces/test/pods/pod1/exec?command=error-command&stdout=true&stderr=true")
-            .andUpgradeToWebSocket()
-            .open(ErrorChannelMessage("{\"metadata\":{},\"status\":\"failed\", \"details\":{}}\n"))
-            .done()
-            .always()
+        factory = TestStandardHttpClientFactory()
+        client = KubernetesClientBuilder()
+                .withHttpClientFactory(factory)
+                .withConfig(ConfigBuilder()
+                        .withNamespace("test")
+                        .build())
+                .build()
+        httpClient = factory.instances.iterator().next()
+
+        val podReadyList = PodListBuilder()
+                .withNewMetadata().endMetadata()
+                .addNewItem()
+                .withNewMetadata()
+                .withName("single-container")
+                .withLabels<String, String>(mapOf("app" to "single-container"))
+                .endMetadata()
+                .withNewSpec().addNewContainer().withName("single-container").endContainer().endSpec()
+                .withNewStatus().addNewCondition().withType("Ready").withStatus("True").endCondition().endStatus()
+                .endItem()
+                .build()
+        httpClient.expect("/api/v1/namespaces/test/pods", 200, client.kubernetesSerialization.asJson(podReadyList))
+        httpClient.expect("/api/v1/namespaces/test/pods/single-container", 200, client.kubernetesSerialization.asJson(podReadyList.items[0]))
+        // "/api/v1/namespaces/test/pods" will be called twice
+        httpClient.expect("/api/v1/namespaces/test/pods", 200, client.kubernetesSerialization.asJson(podReadyList))
     }
 
-    /**
-     * Copied from fabric8 Kubernetes Client repository
-     *
-     * @param pod
-     * @param status
-     * @return
-     */
-    fun createReadyFrom(pod: Pod, status: String): Pod {
-        return PodBuilder(pod)
-            .withNewStatus()
-            .addNewCondition()
-            .withType("Ready")
-            .withStatus(status)
-            .endCondition()
-            .endStatus()
-            .build()
-    }
 
     @AfterEach
     fun tearDown() {
-        server.after()
     }
 
     @Test
     fun testGetPodName() {
-        assertEquals("pod1", ActionCommand(client = server.client).getPodName(mutableMapOf("app" to "pod"), 1))
+        assertEquals("single-container", ActionCommand(client = client).awaitPodName(mapOf("app" to "single-container"), 1))
     }
 
     @Test
     fun testActionSuccess() {
-        val action = Action()
-        action.execCommand = ExecCommand()
-        action.execCommand!!.selector = ExecActionSelector()
-        action.execCommand!!.selector.pod = PodSelector()
-        action.execCommand!!.selector.pod.matchLabels = mutableMapOf("app" to "pod")
-        action.execCommand!!.command = arrayOf("ls")
-        action.execCommand!!.timeoutSeconds = 10L
-
-        action.exec(server.client)
-        assertEquals(
-            "/api/v1/namespaces/test/pods/pod1/exec?command=ls&stdout=true&stderr=true",
-            server.lastRequest.path)
+        val success = StatusBuilder()
+                .withStatus("Success")
+                .build()
+        httpClient.wsExpect("/api/v1/namespaces/test/pods/single-container/exec", buildWsFutureProvider(success))
+
+        val action = Action().apply {
+            execCommand = ExecCommand().apply {
+                selector = ExecActionSelector().apply {
+                    pod = PodSelector().apply {
+                        matchLabels = mapOf("app" to "single-container")
+                    }
+                }
+                command = arrayOf("ls")
+                timeoutSeconds = 10L
+            }
+        }
+        action.exec(this.client)
+
+        val calledUri = httpClient.recordedBuildWebSocketDirects[0].standardWebSocketBuilder.asHttpRequest().uri()
+        assertTrue(calledUri.toString().contains("/api/v1/namespaces/test/pods/single-container/exec"))
+        assertTrue(calledUri.toString().contains("command=ls"))
     }
 
     @Test
     fun testActionFailed() {
-        val action = Action()
-        action.execCommand = ExecCommand()
-        action.execCommand!!.selector = ExecActionSelector()
-        action.execCommand!!.selector.pod = PodSelector()
-        action.execCommand!!.selector.pod.matchLabels = mapOf("app" to "pod")
-        action.execCommand!!.command = arrayOf("error-command")
-        action.execCommand!!.timeoutSeconds = 10L
-
-        assertThrows<ActionCommandFailedException> { run { action.exec(server.client) } }
+        val failed = StatusBuilder()
+                .withStatus("failed")
+                .withNewDetails()
+                .endDetails()
+                .build()
+        httpClient.wsExpect("/api/v1/namespaces/test/pods/single-container/exec", buildWsFutureProvider(failed))
+
+        val action = Action().apply {
+            execCommand = ExecCommand().apply {
+                selector = ExecActionSelector().apply {
+                    pod = PodSelector().apply {
+                        matchLabels = mapOf("app" to "pod")
+                    }
+                }
+                command = arrayOf("exit", "1")
+                timeoutSeconds = 10L
+            }
+        }
+
+        assertThrows<ActionCommandFailedException> { action.exec(this.client) }
+
+        val calledUri = httpClient.recordedBuildWebSocketDirects[0].standardWebSocketBuilder.asHttpRequest().uri()
+        assertTrue(calledUri.toString().contains("/api/v1/namespaces/test/pods/single-container/exec"))
+        assertTrue(calledUri.toString().contains("command=exit"))
+        assertTrue(calledUri.toString().contains("command=1"))
+    }
+
+    private fun buildBodyBytes(prefix: Byte, body: String): ByteBuffer {
+        val original = body.toByteArray(StandardCharsets.UTF_8)
+        return ByteBuffer.allocate(original.size + 1).apply {
+            put(prefix)
+            put(original)
+        }
+    }
+
+    private fun buildWsFutureProvider(status: Status): TestStandardHttpClient.WsFutureProvider {
+        val webSocket = mock<WebSocket> {
+            on { send(ArgumentMatchers.any()) } doReturn(true)
+        }
+        return TestStandardHttpClient.WsFutureProvider { _, l ->
+            l.onOpen(webSocket)
+            val message = buildBodyBytes(3, Serialization.asJson(status))
+            l.onMessage(webSocket, message) // exit
+            CompletableFuture.completedFuture(WebSocketResponse(WebSocketUpgradeResponse(null), webSocket))
+        }
     }
 }
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ConfigMapResourceSetTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ConfigMapResourceSetTest.kt
index 87058706c1a315c98ba098e6c5835f3a57343112..c0bfc158607c28326c99bf7e8ff054db873a0339 100644
--- a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ConfigMapResourceSetTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ConfigMapResourceSetTest.kt
@@ -17,6 +17,7 @@ import org.junit.jupiter.api.AfterEach
 import org.junit.jupiter.api.Assertions.assertEquals
 import org.junit.jupiter.api.Assertions.assertTrue
 import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Disabled
 import org.junit.jupiter.api.Test
 import org.junit.jupiter.api.assertThrows
 import registerResource
@@ -145,6 +146,7 @@ internal class ConfigMapResourceSetTest {
     }
 
     @Test
+    @Disabled("There is no reason for a special treatment of Execution resources.")
     fun testLoadExecution() {
         val stream = javaClass.getResourceAsStream("/k8s-resource-files/test-execution.yaml")
         val execution = this.executionClient.load(stream).get()
@@ -159,6 +161,7 @@ internal class ConfigMapResourceSetTest {
     }
 
     @Test
+    @Disabled("There is no reason for a special treatment of Benchmark resources.")
     fun testLoadBenchmark() {
         val benchmark = BenchmarkCRDummy("example-benchmark").getCR()
         val createdResource = deployAndGetResource(benchmark).getResourceSet(server.client)
@@ -181,7 +184,7 @@ internal class ConfigMapResourceSetTest {
         server.registerResource(serviceMonitorContext)
 
         val stream = javaClass.getResourceAsStream("/k8s-resource-files/test-service-monitor.yaml")
-        val serviceMonitor = server.client.load(stream).get()[0]
+        val serviceMonitor = server.client.load(stream).items().first()
         val createdResource = deployAndGetResource(serviceMonitor).getResourceSet(server.client)
 
         assertEquals(1, createdResource.size)
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/FileSystemResourceSetTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/FileSystemResourceSetTest.kt
index 1c5f32159713e7ace6857caf0f97b43c90cb36e0..3f10f82e9aff869839e3ef1af9f0721f1b7fe617 100644
--- a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/FileSystemResourceSetTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/FileSystemResourceSetTest.kt
@@ -126,6 +126,7 @@ class FileSystemResourceSetTest {
     }
 
     @Test
+    @Disabled("There is no reason for a special treatment of Benchmark resources.")
     fun testLoadBenchmark(@TempDir tempDir: Path) {
         copyTestResourceFile("test-benchmark.yaml", tempDir)
 
@@ -137,6 +138,7 @@ class FileSystemResourceSetTest {
     }
 
     @Test
+    @Disabled("There is no reason for a special treatment of Execution resources.")
     fun testLoadExecution(@TempDir tempDir: Path) {
         copyTestResourceFile("test-execution.yaml", tempDir)
 
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/K8sManagerTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/K8sManagerTest.kt
index 90dd01626a7c18e0b6f8d6018aae54297e758464..fb2d66870fdbc5854acd1d3c7b2051b418f5df29 100644
--- a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/K8sManagerTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/K8sManagerTest.kt
@@ -120,7 +120,7 @@ internal class K8sManagerTest {
         val manager = K8sManager(server.client)
 
         val serviceMonitorStream = javaClass.getResourceAsStream("/k8s-resource-files/test-service-monitor.yaml")
-        val serviceMonitor = server.client.load(serviceMonitorStream).get()[0]
+        val serviceMonitor = server.client.load(serviceMonitorStream).items().first()
 
         manager.deploy(serviceMonitor)
 
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/ExecutionEventHandlerTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/ExecutionEventHandlerTest.kt
index e794ae1638bd6c7f265b3b7ffb08c2494ba76a37..afbbed1ff077749713fee73589005871d487a808 100644
--- a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/ExecutionEventHandlerTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/ExecutionEventHandlerTest.kt
@@ -107,12 +107,11 @@ class ExecutionEventHandlerTest {
         val executionResource = getExecutionFromSystemResource("k8s-resource-files/test-execution.yaml")
         val execution = executionResource.create()
         val executionName = execution.metadata.name
-        stateHandler.setExecutionState(executionName, ExecutionState.RUNNING)
+        //stateHandler.setExecutionState(executionName, ExecutionState.RUNNING)
 
         // Update status of execution
         execution.status.executionState = ExecutionState.RUNNING
-        executionResource.patchStatus(execution)
-
+        this.executionClient.resource(execution).updateStatus()
 
         // Get execution from server
         val executionResponse = this.executionClient.withName(executionName).get()
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/ExecutionEventHandlerTestWithInformer.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/ExecutionEventHandlerTestWithInformer.kt
index 63a669fe67c66b644b6acbabedc5d79afff8ee31..9c894b862d1146fe2a9857f2834c611dc23edeaa 100644
--- a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/ExecutionEventHandlerTestWithInformer.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/ExecutionEventHandlerTestWithInformer.kt
@@ -15,6 +15,7 @@ import rocks.theodolite.kubernetes.model.crd.ExecutionCRD
 import rocks.theodolite.kubernetes.model.crd.ExecutionState
 import java.io.FileInputStream
 import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
 import java.util.stream.Stream
 
 @WithKubernetesTestServer
@@ -51,7 +52,7 @@ class ExecutionEventHandlerTestWithInformer {
         this.controller = mock()
         this.stateHandler = ExecutionStateHandler(server.client)
         this.addCountDownLatch = CountDownLatch(1)
-        this.updateCountDownLatch = CountDownLatch(2)
+        this.updateCountDownLatch = CountDownLatch(1)
         this.deleteCountDownLatch = CountDownLatch(1)
         this.eventHandler = ExecutionEventHandlerWrapper(
             ExecutionEventHandler(this.controller, this.stateHandler),
@@ -103,7 +104,7 @@ class ExecutionEventHandlerTestWithInformer {
         this.executionClient.inform(eventHandler)
 
         // Await informer called
-        this.addCountDownLatch.await()
+        this.addCountDownLatch.await(10, TimeUnit.SECONDS)
         assertEquals(ExecutionState.PENDING, this.executionClient.withName(executionName).get().status.executionState)
     }
 
@@ -130,7 +131,7 @@ class ExecutionEventHandlerTestWithInformer {
         // assertEquals(ExecutionStates.RUNNING, this.executionClient.withName(executionName).get().status.executionState)
 
         // Await informer called
-        this.addCountDownLatch.await()
+        this.addCountDownLatch.await(10, TimeUnit.SECONDS)
         verify(this.controller).stop(true)
         assertEquals(ExecutionState.RESTART, this.executionClient.withName(executionName).get().status.executionState)
     }
@@ -138,13 +139,16 @@ class ExecutionEventHandlerTestWithInformer {
     @Test
     @DisplayName("Test onUpdate method for execution with no status")
     fun testOnUpdateWithoutStatus() {
+        // Start informer
+        this.executionClient.inform(eventHandler)
+
         // Create first version of execution resource
         val firstExecutionResource = getExecutionFromSystemResource("k8s-resource-files/test-execution.yaml")
         val firstExecution = firstExecutionResource.create()
         val executionName = firstExecution.metadata.name
 
-        // Start informer
-        this.executionClient.inform(eventHandler)
+        // Await informer called
+        this.addCountDownLatch.await(10, TimeUnit.SECONDS)
 
         // Get execution from server
         val firstExecutionResponse = this.executionClient.withName(executionName).get()
@@ -155,7 +159,7 @@ class ExecutionEventHandlerTestWithInformer {
         getExecutionFromSystemResource("k8s-resource-files/test-execution-update.yaml").createOrReplace()
 
         // Await informer called
-        this.updateCountDownLatch.await()
+        this.updateCountDownLatch.await(10, TimeUnit.SECONDS)
         // Get execution from server and assert that new status matches expected one
         assertEquals(ExecutionState.PENDING, this.executionClient.withName(executionName).get().status.executionState)
     }
@@ -185,7 +189,7 @@ class ExecutionEventHandlerTestWithInformer {
         getExecutionFromSystemResource("k8s-resource-files/test-execution-update.yaml").createOrReplace()
 
         // Await informer called
-        this.updateCountDownLatch.await()
+        this.updateCountDownLatch.await(10, TimeUnit.SECONDS)
         // Get execution from server and assert that new status matches expected one
         assertEquals(expectedState, this.executionClient.withName(executionName).get().status.executionState)
     }
@@ -222,7 +226,7 @@ class ExecutionEventHandlerTestWithInformer {
         assertNull(secondExecutionResponse)
 
         // Await informer called
-        this.deleteCountDownLatch.await()
+        this.deleteCountDownLatch.await(10, TimeUnit.SECONDS)
 
         verify(this.controller).stop(false)
     }
@@ -258,7 +262,7 @@ class ExecutionEventHandlerTestWithInformer {
         assertNull(secondExecutionResponse)
 
         // Await informer called
-        this.deleteCountDownLatch.await()
+        this.deleteCountDownLatch.await(10, TimeUnit.SECONDS)
 
         verify(this.controller, never()).stop(false)
     }
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/StateHandlerTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/StateHandlerTest.kt
index ebef641d1e0a699ab5e220b0846be654fbefc672..d3447a07dcac8c7429e4b80a927cb92a9b79ea28 100644
--- a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/StateHandlerTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/StateHandlerTest.kt
@@ -25,7 +25,7 @@ class StateHandlerTest {
     fun setUp() {
         server.before()
         val executionStream = javaClass.getResourceAsStream("/k8s-resource-files/test-execution.yaml")
-        val executionResource = server.client.resources(ExecutionCRD::class.java).load(executionStream).get()
+        val executionResource = server.client.resources(ExecutionCRD::class.java).load(executionStream).item()
 
         K8sManager(server.client).deploy(executionResource)
     }
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/GenericResourcePatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/GenericResourcePatcherTest.kt
index e94a513026eee976ff31e2011dab7c8188f8d64c..18604426bbdfef7d10654bc0e015518e65e6f722 100644
--- a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/GenericResourcePatcherTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/GenericResourcePatcherTest.kt
@@ -104,6 +104,6 @@ internal class GenericResourcePatcherTest {
         server.registerResource(serviceMonitorContext)
 
         val serviceMonitorStream = javaClass.getResourceAsStream("/k8s-resource-files/test-service-monitor.yaml")
-        return server.client.load(serviceMonitorStream).get()[0]
+        return server.client.load(serviceMonitorStream).items().first()
     }
 }
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/LabelPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/LabelPatcherTest.kt
index a517992755ce4d57acd7c2c099c3c878d9c1c147..6024834cc6011963305a994d9cb9e63e6a38e744 100644
--- a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/LabelPatcherTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/LabelPatcherTest.kt
@@ -96,6 +96,6 @@ internal class LabelPatcherTest: AbstractPatcherTest() {
         server.registerResource(serviceMonitorContext)
 
         val serviceMonitorStream = javaClass.getResourceAsStream("/k8s-resource-files/test-service-monitor.yaml")
-        return server.client.load(serviceMonitorStream).get()[0]
+        return server.client.load(serviceMonitorStream).items().first()
     }
 }
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NamePatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NamePatcherTest.kt
index 4f0620a5cdf544440b9c0927a7911edfb2fc84be..4cd9b92798a8c50b8ec37009b0ee9ee30ffa72ab 100644
--- a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NamePatcherTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NamePatcherTest.kt
@@ -91,6 +91,6 @@ internal class NamePatcherTest: AbstractPatcherTest() {
         server.registerResource(serviceMonitorContext)
 
         val serviceMonitorStream = javaClass.getResourceAsStream("/k8s-resource-files/test-service-monitor.yaml")
-        return server.client.load(serviceMonitorStream).get()[0]
+        return server.client.load(serviceMonitorStream).items().first()
     }
 }
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ResourceLimitPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ResourceLimitPatcherTest.kt
index 676f512840e2a6c285148ddeb2a12c660933d343..2e067acbee1a9b79181b83712063c6788a4893a2 100644
--- a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ResourceLimitPatcherTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ResourceLimitPatcherTest.kt
@@ -143,6 +143,6 @@ class ResourceLimitPatcherTest {
     }
 
     private fun getDeployment(fileName: String): Deployment {
-        return server.client.apps().deployments().load(javaClass.getResourceAsStream(fileName)).get()
+        return server.client.apps().deployments().load(javaClass.getResourceAsStream(fileName)).item()
     }
 }
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ResourceRequestPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ResourceRequestPatcherTest.kt
index 80102c5481c96fc39ff87ceb8a11f34686e74a59..99d310fd04b9b9ea6c233d6e31b3b482963cbd88 100644
--- a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ResourceRequestPatcherTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ResourceRequestPatcherTest.kt
@@ -143,7 +143,7 @@ class ResourceRequestPatcherTest {
     }
 
     private fun getDeployment(fileName: String): Deployment {
-        return server.client.apps().deployments().load(javaClass.getResourceAsStream(fileName)).get()
+        return server.client.apps().deployments().load(javaClass.getResourceAsStream(fileName)).item()
     }
 
 }
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/SloCheckerFactoryTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/SloCheckerFactoryTest.kt
index 5aaac2ecb7439d71417ce80df056e01aa8b8b8f8..6ed51eab45362e36c63b3bb74761db745b44d39d 100644
--- a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/SloCheckerFactoryTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/SloCheckerFactoryTest.kt
@@ -4,7 +4,6 @@ import io.quarkus.test.junit.QuarkusTest
 import org.junit.jupiter.api.Assertions.*
 import org.junit.jupiter.api.Test
 import org.junit.jupiter.api.assertThrows
-import rocks.theodolite.core.strategies.Metric
 
 @QuarkusTest
 internal class SloCheckerFactoryTest {
@@ -24,8 +23,7 @@ internal class SloCheckerFactoryTest {
                     "threshold" to "1234"
                 ),
                 100,
-                5,
-                Metric.DEMAND
+                5
             )
         }
     }
@@ -43,8 +41,7 @@ internal class SloCheckerFactoryTest {
                     "threshold" to "1234"
                 ),
                 100,
-                5,
-                Metric.DEMAND
+                5
             )
         }
     }
@@ -62,8 +59,7 @@ internal class SloCheckerFactoryTest {
                     "threshold" to "1234"
                 ),
                 100,
-                5,
-                Metric.DEMAND
+                5
             )
         }
     }
@@ -81,8 +77,7 @@ internal class SloCheckerFactoryTest {
                     "threshold" to "1234"
                 ),
                 100,
-                5,
-                Metric.DEMAND
+                5
             )
         }
     }
@@ -100,8 +95,7 @@ internal class SloCheckerFactoryTest {
                     "threshold" to "1234"
                 ),
                 100,
-                5,
-                Metric.DEMAND
+                5
             )
         }
     }
@@ -119,8 +113,7 @@ internal class SloCheckerFactoryTest {
                     "operator" to "lte",
                 ),
                 100,
-                5,
-                Metric.DEMAND
+                5
             )
         }
     }
@@ -138,8 +131,7 @@ internal class SloCheckerFactoryTest {
                 "threshold" to "12.34"
             ),
             100,
-            5,
-            Metric.DEMAND
+            5
         )
         assertInstanceOf(ExternalSloChecker::class.java, sloChecker)
         val threshold = (sloChecker as ExternalSloChecker).metadata["threshold"]
@@ -160,8 +152,7 @@ internal class SloCheckerFactoryTest {
                 "thresholdRelToLoad" to "0.1"
             ),
             100,
-            5,
-            Metric.DEMAND
+            5
         )
         assertTrue(sloChecker is ExternalSloChecker)
         val computedThreshold = (sloChecker as ExternalSloChecker).metadata["threshold"]
@@ -183,8 +174,7 @@ internal class SloCheckerFactoryTest {
                 "thresholdRelToLoad" to "0.1"
             ),
             100,
-            5,
-            Metric.DEMAND
+            5
         )
         assertTrue(sloChecker is ExternalSloChecker)
         val computedThreshold = (sloChecker as ExternalSloChecker).metadata["threshold"]
@@ -205,8 +195,7 @@ internal class SloCheckerFactoryTest {
                 "thresholdRelToResources" to "0.1"
             ),
             100,
-            5,
-            Metric.DEMAND
+            5
         )
         assertTrue(sloChecker is ExternalSloChecker)
         val computedThreshold = (sloChecker as ExternalSloChecker).metadata["threshold"]
@@ -227,8 +216,7 @@ internal class SloCheckerFactoryTest {
                 "thresholdFromExpression" to "1111"
             ),
             8,
-            5,
-            Metric.DEMAND
+            5
         )
         assertTrue(sloChecker is ExternalSloChecker)
         val computedThreshold = (sloChecker as ExternalSloChecker).metadata["threshold"]
@@ -249,8 +237,7 @@ internal class SloCheckerFactoryTest {
                 "thresholdFromExpression" to "L*5"
             ),
             8,
-            5,
-            Metric.DEMAND
+            5
         )
         assertTrue(sloChecker is ExternalSloChecker)
         val computedThreshold = (sloChecker as ExternalSloChecker).metadata["threshold"]
@@ -271,8 +258,7 @@ internal class SloCheckerFactoryTest {
                 "thresholdFromExpression" to "R*((2^L+4)-60)+111"
             ),
             8,
-            5,
-            Metric.DEMAND
+            5
         )
         assertTrue(sloChecker is ExternalSloChecker)
         val computedThreshold = (sloChecker as ExternalSloChecker).metadata["threshold"]
@@ -290,8 +276,7 @@ internal class SloCheckerFactoryTest {
                     "threshold" to "1234"
                 ),
                 100,
-                5,
-                Metric.DEMAND
+                5
             )
         }
     }
@@ -306,8 +291,7 @@ internal class SloCheckerFactoryTest {
                     "threshold" to "1234"
                 ),
                 100,
-                5,
-                Metric.DEMAND
+                5
             )
         }
     }
@@ -323,8 +307,7 @@ internal class SloCheckerFactoryTest {
                     "warmup" to "60",
                 ),
                 100,
-                5,
-                Metric.DEMAND
+                5
             )
         }
     }
@@ -339,8 +322,7 @@ internal class SloCheckerFactoryTest {
                 "threshold" to "12.34"
             ),
             100,
-            5,
-            Metric.DEMAND
+            5
         )
         assertInstanceOf(ExternalSloChecker::class.java, sloChecker)
         val threshold = (sloChecker as ExternalSloChecker).metadata["threshold"]
@@ -358,8 +340,7 @@ internal class SloCheckerFactoryTest {
                 "thresholdRelToLoad" to "0.1"
             ),
             100,
-            5,
-            Metric.DEMAND
+            5
         )
         assertTrue(sloChecker is ExternalSloChecker)
         val computedThreshold = (sloChecker as ExternalSloChecker).metadata["threshold"]
@@ -378,8 +359,7 @@ internal class SloCheckerFactoryTest {
                 "thresholdRelToLoad" to "0.1"
             ),
             100,
-            5,
-            Metric.DEMAND
+            5
         )
         assertTrue(sloChecker is ExternalSloChecker)
         val computedThreshold = (sloChecker as ExternalSloChecker).metadata["threshold"]
@@ -397,8 +377,7 @@ internal class SloCheckerFactoryTest {
                 "thresholdRelToResources" to "0.1"
             ),
             100,
-            5,
-            Metric.DEMAND
+            5
         )
         assertTrue(sloChecker is ExternalSloChecker)
         val computedThreshold = (sloChecker as ExternalSloChecker).metadata["threshold"]
@@ -416,8 +395,7 @@ internal class SloCheckerFactoryTest {
                     "ratio" to "0.123"
                 ),
                 100,
-                5,
-                Metric.DEMAND
+                5
             )
         }
     }
@@ -432,8 +410,7 @@ internal class SloCheckerFactoryTest {
                     "ratio" to "0.123"
                 ),
                 100,
-                5,
-                Metric.DEMAND
+                5
             )
         }
     }
@@ -449,8 +426,7 @@ internal class SloCheckerFactoryTest {
                     "warmup" to "60",
                 ),
                 100,
-                5,
-                Metric.DEMAND
+                5
             )
         }
     }
@@ -465,8 +441,7 @@ internal class SloCheckerFactoryTest {
                 "ratio" to "0.123"
             ),
             100,
-            5,
-            Metric.DEMAND
+            5
         )
         assertInstanceOf(ExternalSloChecker::class.java, sloChecker)
         val threshold = (sloChecker as ExternalSloChecker).metadata["threshold"]
diff --git a/theodolite/src/test/resources/resource-teardown-test-files/load-generator-configmap.yaml b/theodolite/src/test/resources/resource-teardown-test-files/load-generator-configmap.yaml
index d3392e6fef3d050d5f2b44ab362df1d862ab113f..b20ed32959b78d422ab186c91081e9fc0b3bd9fc 100644
--- a/theodolite/src/test/resources/resource-teardown-test-files/load-generator-configmap.yaml
+++ b/theodolite/src/test/resources/resource-teardown-test-files/load-generator-configmap.yaml
@@ -3,10 +3,12 @@ metadata:
   name: load-generator-configmap
 data:
   load-generator-file-1.yaml: |
+    apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: load-generator-file-1
   load-generator-file-2.yaml: |
+    apiVersion: v1
     kind: Service
     metadata:
       name: load-generator-file-2
diff --git a/theodolite/src/test/resources/resource-teardown-test-files/sut-configmap-1.yaml b/theodolite/src/test/resources/resource-teardown-test-files/sut-configmap-1.yaml
index e090c0fa94562e7ddf3fe225ed5be0837018199d..1434032d696bfd2c42a94c7c8f90028a4e6fda01 100644
--- a/theodolite/src/test/resources/resource-teardown-test-files/sut-configmap-1.yaml
+++ b/theodolite/src/test/resources/resource-teardown-test-files/sut-configmap-1.yaml
@@ -3,10 +3,12 @@ metadata:
   name: sut-configmap-1
 data:
   sut-file-1.yaml: |
+    apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: sut-file-1
   sut-file-2.yaml: |
+    apiVersion: v1
     kind: Service
     metadata:
       name: sut-file-2
diff --git a/theodolite/src/test/resources/resource-teardown-test-files/sut-configmap-2.yaml b/theodolite/src/test/resources/resource-teardown-test-files/sut-configmap-2.yaml
index 3c52c47d9f96f45058b4a6017d41b29ad25b8468..d17a2c3b2d03227f0eae3cf8b996766f7a2ed05f 100644
--- a/theodolite/src/test/resources/resource-teardown-test-files/sut-configmap-2.yaml
+++ b/theodolite/src/test/resources/resource-teardown-test-files/sut-configmap-2.yaml
@@ -3,6 +3,7 @@ metadata:
   name: sut-configmap-2
 data:
   sut-file-3.yaml: |
+    apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: sut-file-3