From ebf216829dc07c96401b817fa879364c9b8d7772 Mon Sep 17 00:00:00 2001 From: trompa Date: Tue, 16 Jul 2024 22:05:28 +0200 Subject: [PATCH] #16717 defer provider instantiation in Kubernetes Module (#16726) * #16717 defer provider instatiation * add license header * fix style, ignore new class in jacoco as it is still initialization code --------- Co-authored-by: Alberto Lago Alvarado --- extensions-core/kubernetes-extensions/pom.xml | 2 + .../k8s/discovery/K8sDiscoveryModule.java | 58 +---------- .../K8sDruidLeaderSelectorProvider.java | 97 +++++++++++++++++++ 3 files changed, 101 insertions(+), 56 deletions(-) create mode 100644 extensions-core/kubernetes-extensions/src/main/java/org/apache/druid/k8s/discovery/K8sDruidLeaderSelectorProvider.java diff --git a/extensions-core/kubernetes-extensions/pom.xml b/extensions-core/kubernetes-extensions/pom.xml index 613dfd756ed..e51d1218464 100644 --- a/extensions-core/kubernetes-extensions/pom.xml +++ b/extensions-core/kubernetes-extensions/pom.xml @@ -158,10 +158,12 @@ org/apache/druid/k8s/discovery/K8sDiscoveryModule* + org/apache/druid/k8s/discovery/K8sDruidLeaderSelectorProvider* org/apache/druid/k8s/discovery/DefaultK8sApiClient* org/apache/druid/k8s/discovery/DefaultK8sLeaderElectorFactory* + diff --git a/extensions-core/kubernetes-extensions/src/main/java/org/apache/druid/k8s/discovery/K8sDiscoveryModule.java b/extensions-core/kubernetes-extensions/src/main/java/org/apache/druid/k8s/discovery/K8sDiscoveryModule.java index 6da6819ff4b..b18f03d7f5b 100644 --- a/extensions-core/kubernetes-extensions/src/main/java/org/apache/druid/k8s/discovery/K8sDiscoveryModule.java +++ b/extensions-core/kubernetes-extensions/src/main/java/org/apache/druid/k8s/discovery/K8sDiscoveryModule.java @@ -21,9 +21,7 @@ package org.apache.druid.k8s.discovery; import com.fasterxml.jackson.databind.Module; import com.google.inject.Binder; -import com.google.inject.Inject; import com.google.inject.Key; -import com.google.inject.Provider; import io.kubernetes.client.openapi.ApiClient; import io.kubernetes.client.util.Config; import org.apache.druid.client.coordinator.Coordinator; @@ -34,9 +32,7 @@ import org.apache.druid.discovery.DruidNodeDiscoveryProvider; import org.apache.druid.guice.JsonConfigProvider; import org.apache.druid.guice.LazySingleton; import org.apache.druid.guice.PolyBind; -import org.apache.druid.guice.annotations.Self; import org.apache.druid.initialization.DruidModule; -import org.apache.druid.server.DruidNode; import java.io.IOException; import java.util.Collections; @@ -88,65 +84,15 @@ public class K8sDiscoveryModule implements DruidModule PolyBind.optionBinder(binder, Key.get(DruidLeaderSelector.class, Coordinator.class)) .addBinding(K8S_KEY) .toProvider( - new DruidLeaderSelectorProvider(true) + K8sDruidLeaderSelectorProvider.K8sCoordinatorDruidLeaderSelectorProvider.class ) .in(LazySingleton.class); PolyBind.optionBinder(binder, Key.get(DruidLeaderSelector.class, IndexingService.class)) .addBinding(K8S_KEY) .toProvider( - new DruidLeaderSelectorProvider(false) + K8sDruidLeaderSelectorProvider.K8sIndexingServiceDruidLeaderSelectorProvider.class ) .in(LazySingleton.class); } - - private static class DruidLeaderSelectorProvider implements Provider - { - @Inject - @Self - private DruidNode druidNode; - - @Inject - private PodInfo podInfo; - - @Inject - private K8sDiscoveryConfig discoveryConfig; - - @Inject - private Provider k8sApiClientProvider; - - private boolean isCoordinator; - - DruidLeaderSelectorProvider(boolean isCoordinator) - { - this.isCoordinator = isCoordinator; - } - - @Override - public DruidLeaderSelector get() - { - // Note: these can not be setup in the constructor because injected K8sDiscoveryConfig and PodInfo - // are not available at that time. - String lockResourceName; - String lockResourceNamespace; - - if (isCoordinator) { - lockResourceName = discoveryConfig.getClusterIdentifier() + "-leaderelection-coordinator"; - lockResourceNamespace = discoveryConfig.getCoordinatorLeaderElectionConfigMapNamespace() == null ? - podInfo.getPodNamespace() : discoveryConfig.getCoordinatorLeaderElectionConfigMapNamespace(); - } else { - lockResourceName = discoveryConfig.getClusterIdentifier() + "-leaderelection-overlord"; - lockResourceNamespace = discoveryConfig.getOverlordLeaderElectionConfigMapNamespace() == null ? - podInfo.getPodNamespace() : discoveryConfig.getOverlordLeaderElectionConfigMapNamespace(); - } - - return new K8sDruidLeaderSelector( - druidNode, - lockResourceName, - lockResourceNamespace, - discoveryConfig, - new DefaultK8sLeaderElectorFactory(k8sApiClientProvider.get(), discoveryConfig) - ); - } - } } diff --git a/extensions-core/kubernetes-extensions/src/main/java/org/apache/druid/k8s/discovery/K8sDruidLeaderSelectorProvider.java b/extensions-core/kubernetes-extensions/src/main/java/org/apache/druid/k8s/discovery/K8sDruidLeaderSelectorProvider.java new file mode 100644 index 00000000000..cff6a8bdf46 --- /dev/null +++ b/extensions-core/kubernetes-extensions/src/main/java/org/apache/druid/k8s/discovery/K8sDruidLeaderSelectorProvider.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.k8s.discovery; + +import com.google.inject.Inject; +import com.google.inject.Provider; +import io.kubernetes.client.openapi.ApiClient; +import org.apache.druid.discovery.DruidLeaderSelector; +import org.apache.druid.guice.annotations.Self; +import org.apache.druid.server.DruidNode; + +public abstract class K8sDruidLeaderSelectorProvider implements Provider +{ + @Inject + @Self + private DruidNode druidNode; + + @Inject + private PodInfo podInfo; + + @Inject + private K8sDiscoveryConfig discoveryConfig; + + @Inject + private Provider k8sApiClientProvider; + + private boolean isCoordinator; + + K8sDruidLeaderSelectorProvider(boolean isCoordinator) + { + this.isCoordinator = isCoordinator; + } + + @Override + public DruidLeaderSelector get() + { + // Note: these can not be setup in the constructor because injected K8sDiscoveryConfig and PodInfo + // are not available at that time. + String lockResourceName; + String lockResourceNamespace; + + if (isCoordinator) { + lockResourceName = discoveryConfig.getClusterIdentifier() + "-leaderelection-coordinator"; + lockResourceNamespace = discoveryConfig.getCoordinatorLeaderElectionConfigMapNamespace() == null + ? + podInfo.getPodNamespace() + : discoveryConfig.getCoordinatorLeaderElectionConfigMapNamespace(); + } else { + lockResourceName = discoveryConfig.getClusterIdentifier() + "-leaderelection-overlord"; + lockResourceNamespace = discoveryConfig.getOverlordLeaderElectionConfigMapNamespace() == null ? + podInfo.getPodNamespace() : discoveryConfig.getOverlordLeaderElectionConfigMapNamespace(); + } + + return new K8sDruidLeaderSelector( + druidNode, + lockResourceName, + lockResourceNamespace, + discoveryConfig, + new DefaultK8sLeaderElectorFactory(k8sApiClientProvider.get(), discoveryConfig) + ); + } + + static class K8sCoordinatorDruidLeaderSelectorProvider extends K8sDruidLeaderSelectorProvider + { + @Inject + public K8sCoordinatorDruidLeaderSelectorProvider() + { + super(true); + } + } + + static class K8sIndexingServiceDruidLeaderSelectorProvider extends K8sDruidLeaderSelectorProvider + { + @Inject + public K8sIndexingServiceDruidLeaderSelectorProvider() + { + super(false); + } + } +}