From 63abb4381f3807025bdb538c96685f97cc22a891 Mon Sep 17 00:00:00 2001 From: yue9944882 <291271447@qq.com> Date: Fri, 12 Mar 2021 15:34:57 +0800 Subject: [PATCH] enforcing read-timeout for informer-factory processor via property "kubernetes.informer.clientReadTimeout" --- .../KubernetesInformerFactoryProcessor.java | 23 +++++++++++++ .../KubernetesInformerAutoConfiguration.java | 4 +++ .../config/KubernetesInformerProperties.java | 32 +++++++++++++++++++ .../informer/cache/ReflectorRunnable.java | 4 ++- 4 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 spring/src/main/java/io/kubernetes/client/spring/extended/controller/config/KubernetesInformerProperties.java diff --git a/spring/src/main/java/io/kubernetes/client/spring/extended/controller/KubernetesInformerFactoryProcessor.java b/spring/src/main/java/io/kubernetes/client/spring/extended/controller/KubernetesInformerFactoryProcessor.java index 49f5d3a2f7..ae456e0454 100644 --- a/spring/src/main/java/io/kubernetes/client/spring/extended/controller/KubernetesInformerFactoryProcessor.java +++ b/spring/src/main/java/io/kubernetes/client/spring/extended/controller/KubernetesInformerFactoryProcessor.java @@ -20,9 +20,14 @@ import io.kubernetes.client.openapi.ApiClient; import io.kubernetes.client.spring.extended.controller.annotation.KubernetesInformer; import io.kubernetes.client.spring.extended.controller.annotation.KubernetesInformers; +import io.kubernetes.client.spring.extended.controller.config.KubernetesInformerProperties; +import io.kubernetes.client.spring.extended.controller.factory.KubernetesControllerFactory; import io.kubernetes.client.util.generic.GenericKubernetesApi; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; @@ -45,6 +50,10 @@ public class KubernetesInformerFactoryProcessor public static final int ORDER = 0; + private static final Logger log = LoggerFactory.getLogger(KubernetesControllerFactory.class); + + @Autowired private KubernetesInformerProperties informerProperties; + private ConfigurableListableBeanFactory beanFactory; @Override @@ -122,6 +131,20 @@ private Lister lister(Class type) { private SharedInformer informer( Class type, KubernetesInformer kubernetesInformer) { ApiClient apiClient = this.beanFactory.getBean(ApiClient.class); + + if (apiClient.getHttpClient().readTimeoutMillis() > 0) { + log.warn( + "Enforcing read-timeout of the ApiClient {} to {} so that the watch connection won't abort from client-side", + apiClient, + informerProperties.getClientReadTimeout()); + apiClient.setHttpClient( + apiClient + .getHttpClient() + .newBuilder() + .readTimeout(informerProperties.getClientReadTimeout()) + .build()); + } + SharedInformerFactory sharedInformerFactory = this.beanFactory.getBean(SharedInformerFactory.class); final GenericKubernetesApi api = diff --git a/spring/src/main/java/io/kubernetes/client/spring/extended/controller/config/KubernetesInformerAutoConfiguration.java b/spring/src/main/java/io/kubernetes/client/spring/extended/controller/config/KubernetesInformerAutoConfiguration.java index fe1aa384e6..63dabe5b93 100644 --- a/spring/src/main/java/io/kubernetes/client/spring/extended/controller/config/KubernetesInformerAutoConfiguration.java +++ b/spring/src/main/java/io/kubernetes/client/spring/extended/controller/config/KubernetesInformerAutoConfiguration.java @@ -18,11 +18,15 @@ import io.kubernetes.client.util.ClientBuilder; import java.io.IOException; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration(proxyBeanMethods = false) @ConditionalOnKubernetesInformerEnabled +@EnableConfigurationProperties({ + KubernetesInformerProperties.class, +}) public class KubernetesInformerAutoConfiguration { @Bean diff --git a/spring/src/main/java/io/kubernetes/client/spring/extended/controller/config/KubernetesInformerProperties.java b/spring/src/main/java/io/kubernetes/client/spring/extended/controller/config/KubernetesInformerProperties.java new file mode 100644 index 0000000000..1815d4eae9 --- /dev/null +++ b/spring/src/main/java/io/kubernetes/client/spring/extended/controller/config/KubernetesInformerProperties.java @@ -0,0 +1,32 @@ +/* +Copyright 2021 The Kubernetes Authors. +Licensed 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 io.kubernetes.client.spring.extended.controller.config; + +import io.kubernetes.client.informer.cache.ReflectorRunnable; +import java.time.Duration; +import org.springframework.boot.context.properties.ConfigurationProperties; + +@ConfigurationProperties("kubernetes.informer") +public class KubernetesInformerProperties { + + private Duration clientReadTimeout = ReflectorRunnable.REFLECTOR_WATCH_CLIENTSIDE_TIMEOUT; + + public Duration getClientReadTimeout() { + return clientReadTimeout; + } + + public KubernetesInformerProperties setClientReadTimeout(Duration clientReadTimeout) { + this.clientReadTimeout = clientReadTimeout; + return this; + } +} diff --git a/util/src/main/java/io/kubernetes/client/informer/cache/ReflectorRunnable.java b/util/src/main/java/io/kubernetes/client/informer/cache/ReflectorRunnable.java index e8ce50e5ba..b39d49e2b5 100644 --- a/util/src/main/java/io/kubernetes/client/informer/cache/ReflectorRunnable.java +++ b/util/src/main/java/io/kubernetes/client/informer/cache/ReflectorRunnable.java @@ -37,6 +37,8 @@ public class ReflectorRunnable< ApiType extends KubernetesObject, ApiListType extends KubernetesListObject> implements Runnable { + public static Duration REFLECTOR_WATCH_CLIENTSIDE_TIMEOUT = Duration.ofMinutes(5); + private static final Logger log = LoggerFactory.getLogger(ReflectorRunnable.class); private String lastSyncResourceVersion; @@ -113,7 +115,7 @@ public void run() { new CallGeneratorParams( Boolean.TRUE, lastSyncResourceVersion, - Long.valueOf(Duration.ofMinutes(5).getSeconds()).intValue())); + Long.valueOf(REFLECTOR_WATCH_CLIENTSIDE_TIMEOUT.getSeconds()).intValue())); synchronized (this) { if (!isActive.get()) {