From 1092f6c377ad6fafd3b5f2446d7a18ebb92fae46 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 26 Jul 2023 12:07:25 +0200 Subject: [PATCH] fix: only notify change when kube config exists, isnt empty and complete (#190) Signed-off-by: Andre Dietisheim --- .../intellij/common/utils/ConfigWatcher.java | 49 ++++++++++++++++--- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/redhat/devtools/intellij/common/utils/ConfigWatcher.java b/src/main/java/com/redhat/devtools/intellij/common/utils/ConfigWatcher.java index fa14e67..4130c5f 100644 --- a/src/main/java/com/redhat/devtools/intellij/common/utils/ConfigWatcher.java +++ b/src/main/java/com/redhat/devtools/intellij/common/utils/ConfigWatcher.java @@ -12,19 +12,24 @@ import com.intellij.openapi.diagnostic.Logger; import io.fabric8.kubernetes.api.model.Config; +import io.fabric8.kubernetes.client.internal.KubeConfigUtils; import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.nio.file.FileSystems; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardWatchEventKinds; import java.nio.file.WatchEvent; import java.nio.file.WatchKey; import java.nio.file.WatchService; +import java.util.function.Consumer; public class ConfigWatcher implements Runnable { + private static final Logger LOG = Logger.getInstance(ConfigWatcher.class); + private final Path config; protected Listener listener; @@ -43,8 +48,7 @@ public ConfigWatcher(Path config, Listener listener) { @Override public void run() { - runOnConfigChange(() -> { - Config config = loadConfig(); + runOnConfigChange((Config config) -> { if (config != null) { listener.onUpdate(this, config); } @@ -59,14 +63,13 @@ protected Config loadConfig() { } } - private void runOnConfigChange(Runnable runnable) { + private void runOnConfigChange(Consumer consumer) { try (WatchService service = newWatchService()) { registerWatchService(service); WatchKey key; while ((key = service.take()) != null) { key.pollEvents().stream() - .filter(this::isConfigPath) - .forEach((Void) -> runnable.run()); + .forEach((event) -> consumer.accept(loadConfig(getPath(event)))); key.reset(); } } catch (IOException | InterruptedException e) { @@ -90,11 +93,43 @@ private void registerWatchService(WatchService service) throws IOException { service); } - protected boolean isConfigPath(WatchEvent event) { - Path path = getWatchedPath().resolve((Path) event.context()); + protected boolean isConfigPath(Path path) { return path.equals(config); } + /** + * Returns {@link Config} for the given path if the kube config file + *
    + *
  • exists and
  • + *
  • is not empty and
  • + *
  • is valid yaml
  • + *
+ * Returns {@code null} otherwise. + * + * @param path the path to the kube config + * @return returns true if the kube config that the event points to exists, is not empty and is valid yaml + */ + private Config loadConfig(Path path) { + if (path == null) { + return null; + } + try { + if (Files.exists(path) + && isConfigPath(path) + && Files.size(path) > 0) { + return KubeConfigUtils.parseConfig(path.toFile()); + } + } catch (Exception e) { + // only catch + LOG.warn("Could not load kube config at " + path.toAbsolutePath(), e); + } + return null; + } + + private Path getPath(WatchEvent event) { + return getWatchedPath().resolve((Path) event.context()); + } + private Path getWatchedPath() { return config.getParent(); }