Repository: kroxylicious/kroxylicious (java)

Issue:
Allow bootstrapServers instead of bootstrap_servers
**Describe the bug**

VirtualCluster accepted a property called `bootstrap_servers` which is the only place where the configuration uses underscore naming. Every other configurable property is `camelCase`. So let's add support for calling it `bootstrapServers` and use `@JsonAlias("bootstrap_servers")` for backwards compatibility.



Pull request:
Fix #1715
### Type of change

- Bugfix

### Description

Fix #1715


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6932954f..66bed3b1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@ Format `<github issue/pr number>: <short description>`.
 
 ## SNAPSHOT
 
+* [#1715](https://github.com/kroxylicious/kroxylicious/issues/1715) Deprecate `bootstrap_servers`, replacing it with `bootstrapServers` 
 * [#1698](https://github.com/kroxylicious/kroxylicious/pull/1698) Bump netty.io_uring.version from 0.0.25.Final to 0.0.26.Final #1698
 * [#1672](https://github.com/kroxylicious/kroxylicious/pull/1672) Limited Fortanix DSM backed KMS integration
 * [#1709](https://github.com/kroxylicious/kroxylicious/pull/1709) Deprecate the existing top level `filters` configuration property; add support for named `filterDefinitions`, which can be scoped to a cluster.
@@ -16,6 +17,7 @@ Format `<github issue/pr number>: <short description>`.
 ### Changes, deprecations and removals
 
 * The top level `filters` configuration property is deprecated. Configurations should use `filterDefinitions` and `defaultFilters` instead.
+* The `bootstrap_servers` property of a virtual cluster's `targetCluster` is deprecated. It is replaced by a property called `bootstrapServers`.
 
 ## 0.9.0
 
diff --git a/docs/modules/configuring/con-configuring-target-cluster-connections.adoc b/docs/modules/configuring/con-configuring-target-cluster-connections.adoc
index c211e175..5e8683c9 100644
--- a/docs/modules/configuring/con-configuring-target-cluster-connections.adoc
+++ b/docs/modules/configuring/con-configuring-target-cluster-connections.adoc
@@ -16,7 +16,7 @@ This option is suitable if the target cluster is using a TLS certificate signed
 virtualClusters:
   my-cluster-proxy:
     targetCluster:
-      bootstrap_servers: my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9093
+      bootstrapServers: my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9093
       tls: {}                                         
       #...
 ----
@@ -29,7 +29,7 @@ If it is using a TLS certificate signed by a private CA, you must add truststore
 virtualClusters:
   my-cluster-proxy:
     targetCluster:
-      bootstrap_servers: my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9093
+      bootstrapServers: my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9093
       tls:
         trust:
           storeFile: <path>/trust.p12 # <1>                
@@ -50,7 +50,7 @@ For mTLS, you can add keystore configuration for the virtual cluster too.
 virtualClusters:
   my-cluster-proxy:
     targetCluster:
-      bootstrap_servers: my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9093:9092
+      bootstrapServers: my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9093:9092
       tls:
         key:
           privateKeyFile: <path>/client.key # <1>
@@ -71,7 +71,7 @@ For the purposes of testing outside of a production environment, you can set the
 virtualClusters:
   my-cluster-proxy:
     targetCluster:
-      bootstrap_servers: myprivatecluster:9092
+      bootstrapServers: myprivatecluster:9092
       tls:
         trust:
           insecure: true                                
diff --git a/docs/modules/configuring/con-configuring-virtual-clusters.adoc b/docs/modules/configuring/con-configuring-virtual-clusters.adoc
index fb3d7918..87c1e7b0 100644
--- a/docs/modules/configuring/con-configuring-virtual-clusters.adoc
+++ b/docs/modules/configuring/con-configuring-virtual-clusters.adoc
@@ -8,7 +8,7 @@ When Kroxylicious is deployed, it includes configuration to create virtual clust
 
 A virtual cluster has exactly one target cluster, but many virtual clusters can target the same cluster.
 Each virtual cluster targets a single listener on the target cluster, so multiple listeners on the Kafka side are represented as multiple virtual clusters by the proxy.
-Clients connect to a virtual cluster using a `bootstrap_servers` address.
+Clients connect to a virtual cluster using a `bootstrapServers` address.
 The virtual cluster has a bootstrap address that maps to each broker in the target cluster.
 When a client connects to the proxy, communication is proxied to the target broker by rewriting the address.
 Responses back to clients are rewritten to reflect the appropriate network addresses of the virtual clusters. 
diff --git a/docs/modules/configuring/ref-configuring-proxy-example.adoc b/docs/modules/configuring/ref-configuring-proxy-example.adoc
index cbdc253f..715c3a18 100644
--- a/docs/modules/configuring/ref-configuring-proxy-example.adoc
+++ b/docs/modules/configuring/ref-configuring-proxy-example.adoc
@@ -20,7 +20,7 @@ adminHttp: # <1>
     virtualClusters: # <2>
       my-cluster-proxy: # <3>
         targetCluster:
-          bootstrap_servers: my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9093 # <4>
+          bootstrapServers: my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9093 # <4>
           tls: # <5>
             trust:
               storeFile: /opt/proxy/trust/ca.p12
diff --git a/kroxylicious-app/example-proxy-config.yaml b/kroxylicious-app/example-proxy-config.yaml
index c17b627f..cb95fc2a 100644
--- a/kroxylicious-app/example-proxy-config.yaml
+++ b/kroxylicious-app/example-proxy-config.yaml
@@ -11,7 +11,7 @@ adminHttp:
 virtualClusters:
   demo:
     targetCluster:
-      bootstrap_servers: localhost:9092
+      bootstrapServers: localhost:9092
     clusterNetworkAddressConfigProvider:
       type: PortPerBrokerClusterNetworkAddressConfigProvider
       config:
diff --git a/kroxylicious-kms-provider-aws-kms/DEV_GUIDE.md b/kroxylicious-kms-provider-aws-kms/DEV_GUIDE.md
index 4b4102bf..cf9cff81 100644
--- a/kroxylicious-kms-provider-aws-kms/DEV_GUIDE.md
+++ b/kroxylicious-kms-provider-aws-kms/DEV_GUIDE.md
@@ -40,7 +40,7 @@ your Kafka client off-EC2.
      virtualClusters:
        demo:
          targetCluster:
-           bootstrap_servers: localhost:9092
+           bootstrapServers: localhost:9092
          clusterNetworkAddressConfigProvider:
            type: PortPerBrokerClusterNetworkAddressConfigProvider
            config:
diff --git a/kroxylicious-runtime/src/main/java/io/kroxylicious/proxy/config/TargetCluster.java b/kroxylicious-runtime/src/main/java/io/kroxylicious/proxy/config/TargetCluster.java
index bd988139..88bc54fa 100644
--- a/kroxylicious-runtime/src/main/java/io/kroxylicious/proxy/config/TargetCluster.java
+++ b/kroxylicious-runtime/src/main/java/io/kroxylicious/proxy/config/TargetCluster.java
@@ -9,6 +9,10 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.Optional;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
 import io.kroxylicious.proxy.config.tls.Tls;
@@ -17,9 +21,32 @@ import io.kroxylicious.proxy.service.HostPort;
 /**
  * Represents the target (upstream) kafka cluster.
  */
-public record TargetCluster(@JsonProperty(value = "bootstrap_servers", required = true) String bootstrapServers,
+public record TargetCluster(
+                            @JsonProperty("bootstrapServers") String bootstrapServers,
                             @JsonProperty(value = "tls") Optional<Tls> tls) {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(TargetCluster.class);
+
+    @JsonCreator
+    public static TargetCluster foo(
+                                    @JsonProperty("bootstrapServers") String bootstrapServers,
+                                    @Deprecated(since = "0.10.0", forRemoval = true) @JsonProperty("bootstrap_servers") String deprecatedBootstrapServers,
+                                    @JsonProperty(value = "tls") Optional<Tls> tls) {
+        if (bootstrapServers == null && deprecatedBootstrapServers == null) {
+            throw new IllegalArgumentException("'bootstrapServers' is required in a target cluster.");
+        }
+        if (bootstrapServers != null && deprecatedBootstrapServers != null) {
+            throw new IllegalArgumentException("'bootstrapServers' and 'bootstrap_servers' cannot both be specified in a target cluster.");
+        }
+        if (deprecatedBootstrapServers != null) {
+            LOGGER.warn("'bootstrap_servers' in a target cluster is deprecated and will be removed in a future release: It should be changed to 'bootstrapServers'.");
+            return new TargetCluster(deprecatedBootstrapServers, tls);
+        }
+        else {
+            return new TargetCluster(bootstrapServers, tls);
+        }
+    }
+
     /**
      * A list of host/port pairs to use for establishing the initial connection to the target (upstream) Kafka cluster.
      * This list should be in the form host1:port1,host2:port2,...
diff --git a/kroxylicious-sample/sample-proxy-config.yaml b/kroxylicious-sample/sample-proxy-config.yaml
index 64f70b8e..a54e20d4 100644
--- a/kroxylicious-sample/sample-proxy-config.yaml
+++ b/kroxylicious-sample/sample-proxy-config.yaml
@@ -11,7 +11,7 @@ adminHttp:
 virtualClusters:
   demo:
     targetCluster:
-      bootstrap_servers: localhost:9092
+      bootstrapServers: localhost:9092
     clusterNetworkAddressConfigProvider:
       type: PortPerBrokerClusterNetworkAddressConfigProvider
       config:
diff --git a/kubernetes-examples/filters/multi-tenant/base/kroxylicious/kroxylicious-config.yaml b/kubernetes-examples/filters/multi-tenant/base/kroxylicious/kroxylicious-config.yaml
index c456bed1..5e5d16bb 100644
--- a/kubernetes-examples/filters/multi-tenant/base/kroxylicious/kroxylicious-config.yaml
+++ b/kubernetes-examples/filters/multi-tenant/base/kroxylicious/kroxylicious-config.yaml
@@ -22,7 +22,7 @@ data:
     virtualClusters:
       devenv1:
         targetCluster:
-          bootstrap_servers: my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092
+          bootstrapServers: my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092
         clusterNetworkAddressConfigProvider:
           type: PortPerBrokerClusterNetworkAddressConfigProvider
           config:
@@ -31,7 +31,7 @@ data:
         logFrames: false
       devenv2:
         targetCluster:
-          bootstrap_servers: my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092
+          bootstrapServers: my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092
         clusterNetworkAddressConfigProvider:
           type: PortPerBrokerClusterNetworkAddressConfigProvider
           config:
diff --git a/kubernetes-examples/filters/record-encryption/base/kroxylicious/kroxylicious-config.yaml b/kubernetes-examples/filters/record-encryption/base/kroxylicious/kroxylicious-config.yaml
index 1bbda8a4..99702074 100644
--- a/kubernetes-examples/filters/record-encryption/base/kroxylicious/kroxylicious-config.yaml
+++ b/kubernetes-examples/filters/record-encryption/base/kroxylicious/kroxylicious-config.yaml
@@ -26,7 +26,7 @@ data:
             bootstrapAddress: minikube:30192
         targetCluster:
           # declares the kafka cluster that is being proxied
-          bootstrap_servers: my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092
+          bootstrapServers: my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092
         logFrames: false
     filterDefinitions:
     - name: encrypt
diff --git a/kubernetes-examples/network-topologies/portperbroker_plain/base/kroxylicious/kroxylicious-config.yaml b/kubernetes-examples/network-topologies/portperbroker_plain/base/kroxylicious/kroxylicious-config.yaml
index 5535b055..13e6369d 100644
--- a/kubernetes-examples/network-topologies/portperbroker_plain/base/kroxylicious/kroxylicious-config.yaml
+++ b/kubernetes-examples/network-topologies/portperbroker_plain/base/kroxylicious/kroxylicious-config.yaml
@@ -17,7 +17,7 @@ data:
     virtualClusters:
       demo:
         targetCluster:
-          bootstrap_servers: my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092
+          bootstrapServers: my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092
         clusterNetworkAddressConfigProvider:
           type: PortPerBrokerClusterNetworkAddressConfigProvider
           config:
diff --git a/kubernetes-examples/network-topologies/rangeawareportperbroker_plain/base/kroxylicious/kroxylicious-config.yaml b/kubernetes-examples/network-topologies/rangeawareportperbroker_plain/base/kroxylicious/kroxylicious-config.yaml
index 611793eb..c3984c2e 100644
--- a/kubernetes-examples/network-topologies/rangeawareportperbroker_plain/base/kroxylicious/kroxylicious-config.yaml
+++ b/kubernetes-examples/network-topologies/rangeawareportperbroker_plain/base/kroxylicious/kroxylicious-config.yaml
@@ -17,7 +17,7 @@ data:
     virtualClusters:
       demo:
         targetCluster:
-          bootstrap_servers: my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092
+          bootstrapServers: my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092
         clusterNetworkAddressConfigProvider:
           type: RangeAwarePortPerNodeClusterNetworkAddressConfigProvider
           config:
diff --git a/kubernetes-examples/network-topologies/snirouting_tls/base/kroxylicious/kroxylicious-config.yaml b/kubernetes-examples/network-topologies/snirouting_tls/base/kroxylicious/kroxylicious-config.yaml
index ea73db4f..1542e339 100644
--- a/kubernetes-examples/network-topologies/snirouting_tls/base/kroxylicious/kroxylicious-config.yaml
+++ b/kubernetes-examples/network-topologies/snirouting_tls/base/kroxylicious/kroxylicious-config.yaml
@@ -17,7 +17,7 @@ data:
     virtualClusters:
       my-cluster-proxy:
         targetCluster:
-          bootstrap_servers: my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9093
+          bootstrapServers: my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9093
           tls:
             trust:
               storeFile: /opt/kroxylicious/trust/ca.p12


Test patch:
diff --git a/kroxylicious-app/src/test/resources/proxy-config.yaml b/kroxylicious-app/src/test/resources/proxy-config.yaml
index b9e45013..4b0f73f0 100644
--- a/kroxylicious-app/src/test/resources/proxy-config.yaml
+++ b/kroxylicious-app/src/test/resources/proxy-config.yaml
@@ -11,7 +11,7 @@ adminHttp:
 virtualClusters:
   demo:
     targetCluster:
-      bootstrap_servers: localhost:9092
+      bootstrapServers: localhost:9092
     clusterNetworkAddressConfigProvider:
       type: PortPerBrokerClusterNetworkAddressConfigProvider
       config:
diff --git a/kroxylicious-integration-test-support/src/test/java/io/kroxylicious/proxy/config/ConfigurationTest.java b/kroxylicious-integration-test-support/src/test/java/io/kroxylicious/proxy/config/ConfigurationTest.java
index fabc9a70..67c1ff21 100644
--- a/kroxylicious-integration-test-support/src/test/java/io/kroxylicious/proxy/config/ConfigurationTest.java
+++ b/kroxylicious-integration-test-support/src/test/java/io/kroxylicious/proxy/config/ConfigurationTest.java
@@ -6,6 +6,7 @@
 
 package io.kroxylicious.proxy.config;
 
+import java.io.IOException;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -18,6 +19,7 @@ import org.junit.jupiter.params.provider.MethodSource;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.exc.ValueInstantiationException;
 import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
 import com.flipkart.zjsonpatch.JsonDiff;
 
@@ -34,6 +36,60 @@ class ConfigurationTest {
     private static final ObjectMapper MAPPER = new ObjectMapper(new YAMLFactory());
     private final ConfigParser configParser = new ConfigParser();
 
+    @Test
+    void shouldAcceptOldBootstrapServers() throws IOException {
+        var vc = MAPPER.readValue(
+                """
+                              targetCluster:
+                                bootstrap_servers: kafka.example:1234
+                              clusterNetworkAddressConfigProvider:
+                                type: SniRoutingClusterNetworkAddressConfigProvider
+                                config:
+                                  bootstrapAddress: cluster1:9192
+                                  brokerAddressPattern: broker-$(nodeId)
+                        """, VirtualCluster.class);
+
+        TargetCluster targetCluster = vc.targetCluster();
+        assertThat(targetCluster).isNotNull();
+        assertThat(targetCluster.bootstrapServers()).isEqualTo("kafka.example:1234");
+    }
+
+    @Test
+    void shouldRejectOldAndNewBootstrapServers() throws IOException {
+        assertThatThrownBy(() -> {
+            MAPPER.readValue(
+                    """
+                                  targetCluster:
+                                    bootstrap_servers: kafka.example:1234
+                                    bootstrapServers: kafka.example:1234
+                                  clusterNetworkAddressConfigProvider:
+                                    type: SniRoutingClusterNetworkAddressConfigProvider
+                                    config:
+                                      bootstrapAddress: cluster1:9192
+                                      brokerAddressPattern: broker-$(nodeId)
+                            """, VirtualCluster.class);
+        }).isInstanceOf(ValueInstantiationException.class)
+                .hasCauseInstanceOf(IllegalArgumentException.class)
+                .hasMessageContaining("'bootstrapServers' and 'bootstrap_servers' cannot both be specified in a target cluster.");
+    }
+
+    @Test
+    void shouldRequireOldOrNewBootstrapServers() throws IOException {
+        assertThatThrownBy(() -> {
+            MAPPER.readValue(
+                    """
+                                  targetCluster: {}
+                                  clusterNetworkAddressConfigProvider:
+                                    type: SniRoutingClusterNetworkAddressConfigProvider
+                                    config:
+                                      bootstrapAddress: cluster1:9192
+                                      brokerAddressPattern: broker-$(nodeId)
+                            """, VirtualCluster.class);
+        }).isInstanceOf(ValueInstantiationException.class)
+                .hasCauseInstanceOf(IllegalArgumentException.class)
+                .hasMessageContaining("'bootstrapServers' is required in a target cluster.");
+    }
+
     public static Stream<Arguments> fluentApiConfigYamlFidelity() {
         NamedFilterDefinition filter = new NamedFilterDefinitionBuilder("filter-1", ExampleFilterFactory.class.getSimpleName())
                 .withConfig("examplePlugin", "ExamplePluginInstance",
@@ -88,7 +144,7 @@ class ConfigurationTest {
                                 virtualClusters:
                                   demo:
                                     targetCluster:
-                                      bootstrap_servers: kafka.example:1234
+                                      bootstrapServers: kafka.example:1234
                                     clusterNetworkAddressConfigProvider:
                                       type: SniRoutingClusterNetworkAddressConfigProvider
                                       config:
@@ -119,7 +175,7 @@ class ConfigurationTest {
                                 virtualClusters:
                                   demo:
                                     targetCluster:
-                                      bootstrap_servers: kafka.example:1234
+                                      bootstrapServers: kafka.example:1234
                                     tls:
                                        key:
                                          certificateFile: /tmp/cert
@@ -162,7 +218,7 @@ class ConfigurationTest {
                                 virtualClusters:
                                   demo:
                                     targetCluster:
-                                      bootstrap_servers: kafka.example:1234
+                                      bootstrapServers: kafka.example:1234
                                     tls:
                                        key:
                                          certificateFile: /tmp/cert
@@ -198,7 +254,7 @@ class ConfigurationTest {
                                 virtualClusters:
                                   demo:
                                     targetCluster:
-                                      bootstrap_servers: kafka.example:1234
+                                      bootstrapServers: kafka.example:1234
                                       tls: {}
                                     clusterNetworkAddressConfigProvider:
                                       type: SniRoutingClusterNetworkAddressConfigProvider
@@ -230,7 +286,7 @@ class ConfigurationTest {
                                 virtualClusters:
                                   demo:
                                     targetCluster:
-                                      bootstrap_servers: kafka.example:1234
+                                      bootstrapServers: kafka.example:1234
                                       tls:
                                          trust:
                                             storeFile: /tmp/client.jks
@@ -267,7 +323,7 @@ class ConfigurationTest {
                                 virtualClusters:
                                   demo:
                                     targetCluster:
-                                      bootstrap_servers: kafka.example:1234
+                                      bootstrapServers: kafka.example:1234
                                       tls:
                                          trust:
                                             storeFile: /tmp/client.jks
@@ -300,7 +356,7 @@ class ConfigurationTest {
                                 virtualClusters:
                                   demo:
                                     targetCluster:
-                                      bootstrap_servers: kafka.example:1234
+                                      bootstrapServers: kafka.example:1234
                                       tls:
                                          trust:
                                             insecure: true
diff --git a/kroxylicious-operator/src/test/resources/DerivedResourcesTest/filter-resource-not-found/out-Secret-example.yaml b/kroxylicious-operator/src/test/resources/DerivedResourcesTest/filter-resource-not-found/out-Secret-example.yaml
index afd64282..49af448c 100644
--- a/kroxylicious-operator/src/test/resources/DerivedResourcesTest/filter-resource-not-found/out-Secret-example.yaml
+++ b/kroxylicious-operator/src/test/resources/DerivedResourcesTest/filter-resource-not-found/out-Secret-example.yaml
@@ -40,7 +40,7 @@ stringData:
     virtualClusters:
       bar:
         targetCluster:
-          bootstrap_servers: "my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092"
+          bootstrapServers: "my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092"
         clusterNetworkAddressConfigProvider:
           type: "PortPerBrokerClusterNetworkAddressConfigProvider"
           config:
diff --git a/kroxylicious-operator/src/test/resources/DerivedResourcesTest/minimal/out-Secret-minimal.yaml b/kroxylicious-operator/src/test/resources/DerivedResourcesTest/minimal/out-Secret-minimal.yaml
index 7d8d56d8..5f6b4a63 100644
--- a/kroxylicious-operator/src/test/resources/DerivedResourcesTest/minimal/out-Secret-minimal.yaml
+++ b/kroxylicious-operator/src/test/resources/DerivedResourcesTest/minimal/out-Secret-minimal.yaml
@@ -31,7 +31,7 @@ stringData:
     virtualClusters:
       one:
         targetCluster:
-          bootstrap_servers: "my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092"
+          bootstrapServers: "my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092"
         clusterNetworkAddressConfigProvider:
           type: "PortPerBrokerClusterNetworkAddressConfigProvider"
           config:
diff --git a/kroxylicious-operator/src/test/resources/DerivedResourcesTest/two-clusters/out-Secret-twocluster.yaml b/kroxylicious-operator/src/test/resources/DerivedResourcesTest/two-clusters/out-Secret-twocluster.yaml
index b940eeb3..2ca0644c 100644
--- a/kroxylicious-operator/src/test/resources/DerivedResourcesTest/two-clusters/out-Secret-twocluster.yaml
+++ b/kroxylicious-operator/src/test/resources/DerivedResourcesTest/two-clusters/out-Secret-twocluster.yaml
@@ -31,7 +31,7 @@ stringData:
     virtualClusters:
       foo:
         targetCluster:
-          bootstrap_servers: "first-kafka.kafka1.svc.cluster.local:9092"
+          bootstrapServers: "first-kafka.kafka1.svc.cluster.local:9092"
         clusterNetworkAddressConfigProvider:
           type: "PortPerBrokerClusterNetworkAddressConfigProvider"
           config:
@@ -41,7 +41,7 @@ stringData:
             numberOfBrokerPorts: 3
       bar:
         targetCluster:
-          bootstrap_servers: "second-kafka.kafka2.svc.cluster.local:9092"
+          bootstrapServers: "second-kafka.kafka2.svc.cluster.local:9092"
         clusterNetworkAddressConfigProvider:
           type: "PortPerBrokerClusterNetworkAddressConfigProvider"
           config:
diff --git a/kroxylicious-operator/src/test/resources/DerivedResourcesTest/two-filters/out-Secret-example.yaml b/kroxylicious-operator/src/test/resources/DerivedResourcesTest/two-filters/out-Secret-example.yaml
index b5adfcfc..06221116 100644
--- a/kroxylicious-operator/src/test/resources/DerivedResourcesTest/two-filters/out-Secret-example.yaml
+++ b/kroxylicious-operator/src/test/resources/DerivedResourcesTest/two-filters/out-Secret-example.yaml
@@ -40,7 +40,7 @@ stringData:
     virtualClusters:
       foo:
         targetCluster:
-          bootstrap_servers: "my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092"
+          bootstrapServers: "my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092"
         clusterNetworkAddressConfigProvider:
           type: "PortPerBrokerClusterNetworkAddressConfigProvider"
           config:
diff --git a/kroxylicious-operator/src/test/resources/DerivedResourcesTest/use-pod-template-spec/out-Secret-use-pod-template-spec.yaml b/kroxylicious-operator/src/test/resources/DerivedResourcesTest/use-pod-template-spec/out-Secret-use-pod-template-spec.yaml
index 0f44bb0b..98183a00 100644
--- a/kroxylicious-operator/src/test/resources/DerivedResourcesTest/use-pod-template-spec/out-Secret-use-pod-template-spec.yaml
+++ b/kroxylicious-operator/src/test/resources/DerivedResourcesTest/use-pod-template-spec/out-Secret-use-pod-template-spec.yaml
@@ -31,7 +31,7 @@ stringData:
     virtualClusters:
       one:
         targetCluster:
-          bootstrap_servers: "my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092"
+          bootstrapServers: "my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092"
         clusterNetworkAddressConfigProvider:
           type: "PortPerBrokerClusterNetworkAddressConfigProvider"
           config:
diff --git a/kroxylicious-runtime/src/test/java/io/kroxylicious/proxy/KafkaProxyTest.java b/kroxylicious-runtime/src/test/java/io/kroxylicious/proxy/KafkaProxyTest.java
index 7b9856f8..39048d4f 100644
--- a/kroxylicious-runtime/src/test/java/io/kroxylicious/proxy/KafkaProxyTest.java
+++ b/kroxylicious-runtime/src/test/java/io/kroxylicious/proxy/KafkaProxyTest.java
@@ -39,7 +39,7 @@ class KafkaProxyTest {
                    virtualClusters:
                      demo1:
                        targetCluster:
-                         bootstrap_servers: kafka.example:1234
+                         bootstrapServers: kafka.example:1234
                        clusterNetworkAddressConfigProvider:
                          type: PortPerBrokerClusterNetworkAddressConfigProvider
                          config:
@@ -61,7 +61,7 @@ class KafkaProxyTest {
                 virtualClusters:
                   demo1:
                     targetCluster:
-                      bootstrap_servers: kafka.example:1234
+                      bootstrapServers: kafka.example:1234
                     clusterNetworkAddressConfigProvider:
                       type: PortPerBrokerClusterNetworkAddressConfigProvider
                       config:
@@ -69,7 +69,7 @@ class KafkaProxyTest {
                         numberOfBrokerPorts: 1
                   demo2:
                     targetCluster:
-                      bootstrap_servers: kafka.example:1234
+                      bootstrapServers: kafka.example:1234
                     clusterNetworkAddressConfigProvider:
                       type: PortPerBrokerClusterNetworkAddressConfigProvider
                       config:
@@ -80,7 +80,7 @@ class KafkaProxyTest {
                         virtualClusters:
                           demo1:
                             targetCluster:
-                              bootstrap_servers: kafka.example:1234
+                              bootstrapServers: kafka.example:1234
                             clusterNetworkAddressConfigProvider:
                               type: PortPerBrokerClusterNetworkAddressConfigProvider
                               config:
@@ -89,7 +89,7 @@ class KafkaProxyTest {
                                 numberOfBrokerPorts: 2
                           demo2:
                             targetCluster:
-                              bootstrap_servers: kafka.example:1234
+                              bootstrapServers: kafka.example:1234
                             clusterNetworkAddressConfigProvider:
                               type: PortPerBrokerClusterNetworkAddressConfigProvider
                               config:
@@ -119,7 +119,7 @@ class KafkaProxyTest {
                         bootstrapAddress: cluster1:9192
                         brokerAddressPattern:  broker-$(nodeId)
                     targetCluster:
-                      bootstrap_servers: kafka.example:1234
+                      bootstrapServers: kafka.example:1234
                 """, "Cluster endpoint provider requires server TLS, but this virtual cluster does not define it"));
     }
 
diff --git a/kroxylicious-runtime/src/test/java/io/kroxylicious/proxy/config/ConfigParserTest.java b/kroxylicious-runtime/src/test/java/io/kroxylicious/proxy/config/ConfigParserTest.java
index 7ab3c810..18d1a034 100644
--- a/kroxylicious-runtime/src/test/java/io/kroxylicious/proxy/config/ConfigParserTest.java
+++ b/kroxylicious-runtime/src/test/java/io/kroxylicious/proxy/config/ConfigParserTest.java
@@ -64,7 +64,7 @@ class ConfigParserTest {
                         virtualClusters:
                           demo1:
                             targetCluster:
-                              bootstrap_servers: kafka.example:1234
+                              bootstrapServers: kafka.example:1234
                             clusterNetworkAddressConfigProvider:
                               type: PortPerBrokerClusterNetworkAddressConfigProvider
                               config:
@@ -77,7 +77,7 @@ class ConfigParserTest {
                         virtualClusters:
                           demo1:
                             targetCluster:
-                              bootstrap_servers: kafka.example:1234
+                              bootstrapServers: kafka.example:1234
                             clusterNetworkAddressConfigProvider:
                               type: RangeAwarePortPerNodeClusterNetworkAddressConfigProvider
                               config:
@@ -94,7 +94,7 @@ class ConfigParserTest {
                         virtualClusters:
                           demo1:
                             targetCluster:
-                              bootstrap_servers: kafka.example:1234
+                              bootstrapServers: kafka.example:1234
                             clusterNetworkAddressConfigProvider:
                               type: SniRoutingClusterNetworkAddressConfigProvider
                               config:
@@ -111,7 +111,7 @@ class ConfigParserTest {
                                     password: password
                                   storeType: JKS
                             targetCluster:
-                              bootstrap_servers: kafka.example:1234
+                              bootstrapServers: kafka.example:1234
                               tls:
                                 trust:
                                  storeFile: /tmp/foo.jks
@@ -134,7 +134,7 @@ class ConfigParserTest {
                                     passwordFile: /tmp/password.txt
                                   storeType: JKS
                             targetCluster:
-                              bootstrap_servers: kafka.example:1234
+                              bootstrapServers: kafka.example:1234
                               tls:
                                 trust:
                                  storeFile: /tmp/foo.jks
@@ -239,7 +239,7 @@ class ConfigParserTest {
                 virtualClusters:
                   myAwesomeCluster:
                     targetCluster:
-                      bootstrap_servers: kafka.example:1234
+                      bootstrapServers: kafka.example:1234
                     clusterNetworkAddressConfigProvider:
                       type: PortPerBrokerClusterNetworkAddressConfigProvider
                       config:
@@ -264,7 +264,7 @@ class ConfigParserTest {
                 virtualClusters:
                   demo1:
                     targetCluster:
-                      bootstrap_servers: kafka.example:1234
+                      bootstrapServers: kafka.example:1234
                     clusterNetworkAddressConfigProvider:
                       type: PortPerBrokerClusterNetworkAddressConfigProvider
                       config:
@@ -274,7 +274,7 @@ class ConfigParserTest {
                         brokerStartPort: 9193
                   demo1:
                     targetCluster:
-                      bootstrap_servers: magic-kafka.example:1234
+                      bootstrapServers: magic-kafka.example:1234
                     clusterNetworkAddressConfigProvider:
                       type: PortPerBrokerClusterNetworkAddressConfigProvider
                       config:
diff --git a/kroxylicious-runtime/src/test/resources/config.yaml b/kroxylicious-runtime/src/test/resources/config.yaml
index 509571c9..408f53d5 100644
--- a/kroxylicious-runtime/src/test/resources/config.yaml
+++ b/kroxylicious-runtime/src/test/resources/config.yaml
@@ -14,7 +14,7 @@ adminHttp:
 virtualClusters:
   demo:
     targetCluster:
-      bootstrap_servers: localhost:9092
+      bootstrapServers: localhost:9092
     clusterNetworkAddressConfigProvider:
       type: PortPerBrokerClusterNetworkAddressConfigProvider
       config:
diff --git a/kroxylicious-systemtests/src/main/java/io/kroxylicious/systemtests/templates/kroxylicious/KroxyliciousConfigMapTemplates.java b/kroxylicious-systemtests/src/main/java/io/kroxylicious/systemtests/templates/kroxylicious/KroxyliciousConfigMapTemplates.java
index 46ceda52..3119cf21 100644
--- a/kroxylicious-systemtests/src/main/java/io/kroxylicious/systemtests/templates/kroxylicious/KroxyliciousConfigMapTemplates.java
+++ b/kroxylicious-systemtests/src/main/java/io/kroxylicious/systemtests/templates/kroxylicious/KroxyliciousConfigMapTemplates.java
@@ -111,7 +111,7 @@ public final class KroxyliciousConfigMapTemplates {
                         bootstrapAddress: localhost:9292
                         brokerAddressPattern: %s
                     targetCluster:
-                      bootstrap_servers: %s-kafka-bootstrap.%s.svc.cluster.local:9092
+                      bootstrapServers: %s-kafka-bootstrap.%s.svc.cluster.local:9092
                     logFrames: false
                 filters:
                 %s
@@ -127,7 +127,7 @@ public final class KroxyliciousConfigMapTemplates {
                 virtualClusters:
                   demo:
                     targetCluster:
-                      bootstrap_servers: %s-kafka-bootstrap.%s.svc.cluster.local:9092
+                      bootstrapServers: %s-kafka-bootstrap.%s.svc.cluster.local:9092
                     clusterNetworkAddressConfigProvider:
                       type: PortPerBrokerClusterNetworkAddressConfigProvider
                       config:
@@ -153,7 +153,7 @@ public final class KroxyliciousConfigMapTemplates {
                 virtualClusters:
                   demo:
                     targetCluster:
-                      bootstrap_servers: %s:9094
+                      bootstrapServers: %s:9094
                     clusterNetworkAddressConfigProvider:
                       type: PortPerBrokerClusterNetworkAddressConfigProvider
                       config:
diff --git a/performance-tests/02-no-filters/config.yaml b/performance-tests/02-no-filters/config.yaml
index f7718b30..6be856c8 100644
--- a/performance-tests/02-no-filters/config.yaml
+++ b/performance-tests/02-no-filters/config.yaml
@@ -11,7 +11,7 @@ adminHttp:
 virtualClusters:
   demo:
     targetCluster:
-      bootstrap_servers: broker1:9092
+      bootstrapServers: broker1:9092
     clusterNetworkAddressConfigProvider:
       type: PortPerBrokerClusterNetworkAddressConfigProvider
       config:
diff --git a/performance-tests/03-transform-filter/config.yaml b/performance-tests/03-transform-filter/config.yaml
index f5bcdc86..4c6099b0 100644
--- a/performance-tests/03-transform-filter/config.yaml
+++ b/performance-tests/03-transform-filter/config.yaml
@@ -11,7 +11,7 @@ adminHttp:
 virtualClusters:
   demo:
     targetCluster:
-      bootstrap_servers: broker1:9092
+      bootstrapServers: broker1:9092
     clusterNetworkAddressConfigProvider:
       type: PortPerBrokerClusterNetworkAddressConfigProvider
       config:
diff --git a/performance-tests/04-record-encryption-filter/config.yaml b/performance-tests/04-record-encryption-filter/config.yaml
index face5035..29bb4181 100644
--- a/performance-tests/04-record-encryption-filter/config.yaml
+++ b/performance-tests/04-record-encryption-filter/config.yaml
@@ -11,7 +11,7 @@ adminHttp:
 virtualClusters:
   demo:
     targetCluster:
-      bootstrap_servers: broker1:9092
+      bootstrapServers: broker1:9092
     clusterNetworkAddressConfigProvider:
       type: PortPerBrokerClusterNetworkAddressConfigProvider
       config: