From 108e796a73212373f375b6e74e12a71b1e4b3be1 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 18 Sep 2024 21:04:27 +0200 Subject: [PATCH] fix: update tree, query cluster info and send telemetry in backgroud (#912) Signed-off-by: Andre Dietisheim --- .../intellij/openshift/WindowToolFactory.java | 7 ++- .../application/ApplicationsRootNode.java | 21 ++++---- .../ApplicationsTreeStructure.java | 6 +-- .../tools/intellij/openshift/utils/Cli.java | 48 +++++++++++-------- .../intellij/openshift/utils/oc/OcCli.java | 10 ++-- .../intellij/openshift/utils/odo/OdoCli.java | 46 +++++++++--------- 6 files changed, 76 insertions(+), 62 deletions(-) diff --git a/src/main/java/org/jboss/tools/intellij/openshift/WindowToolFactory.java b/src/main/java/org/jboss/tools/intellij/openshift/WindowToolFactory.java index f9c34ce00..8247bf930 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/WindowToolFactory.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/WindowToolFactory.java @@ -24,6 +24,7 @@ import com.intellij.ui.tree.AsyncTreeModel; import com.intellij.ui.tree.StructureTreeModel; import com.intellij.ui.treeStructure.Tree; +import com.intellij.util.concurrency.Invoker; import com.redhat.devtools.intellij.common.tree.MutableModelSynchronizer; import com.redhat.devtools.intellij.common.tree.TreeHelper; import com.redhat.devtools.intellij.common.utils.IDEAContentFactory; @@ -45,7 +46,11 @@ public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindo panel.setLayout(new BorderLayout()); Content content = contentFactory.createContent(panel, "", false); ApplicationsTreeStructure structure = new ApplicationsTreeStructure(project, content); - StructureTreeModel model = new StructureTreeModel<>(structure, content); + StructureTreeModel model = new StructureTreeModel<>( + structure, + null, + Invoker.forBackgroundPoolWithoutReadAction(content), + content); content.setDisposer(structure); new MutableModelSynchronizer<>(model, structure, structure); Tree tree = new Tree(new AsyncTreeModel(model, content)); diff --git a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ApplicationsRootNode.java b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ApplicationsRootNode.java index b981736e7..99c275cfb 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ApplicationsRootNode.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ApplicationsRootNode.java @@ -14,6 +14,7 @@ import com.intellij.openapi.Disposable; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.ModuleListener; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; @@ -24,6 +25,13 @@ import com.redhat.devtools.intellij.common.utils.ConfigWatcher; import com.redhat.devtools.intellij.common.utils.ExecHelper; import io.fabric8.kubernetes.api.model.Config; +import java.io.File; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; import org.jboss.tools.intellij.openshift.actions.NotificationUtils; import org.jboss.tools.intellij.openshift.utils.ProjectUtils; import org.jboss.tools.intellij.openshift.utils.ToolFactory; @@ -38,16 +46,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.File; -import java.io.IOException; -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletableFuture; - public class ApplicationsRootNode - implements ModuleListener, ConfigWatcher.Listener, ProcessingNode, StructureAwareNode, ParentableNode, Disposable { + implements ModuleListener, ConfigWatcher.Listener, ProcessingNode, StructureAwareNode, ParentableNode, Disposable, DumbAware { private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationsRootNode.class); private final Project project; @@ -102,7 +102,8 @@ private CompletableFuture doGetOdo() { public CompletableFuture getOdo() { return doGetOdo() .whenComplete((ApplicationRootNodeOdo odo, Throwable err) -> { - if (odo.isDownloaded()) { + if (odo != null + && odo.isDownloaded()) { structure.fireModified(this); } }); diff --git a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ApplicationsTreeStructure.java b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ApplicationsTreeStructure.java index 30d78f08f..683f21a4f 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ApplicationsTreeStructure.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ApplicationsTreeStructure.java @@ -163,7 +163,7 @@ private Object getCurrentNamespace(ApplicationsRootNode element) { } } } catch (Exception e) { - node = createErrorNode(element, e); + node = createCurrentNamespaceErrorNode(element, e); element.setLogged(false); } return node; @@ -188,7 +188,7 @@ private Object[] createHelmRepositoriesChildren(HelmRepositoriesNode parent) { } } - private MessageNode createErrorNode(ParentableNode parent, Exception e) { + private MessageNode createCurrentNamespaceErrorNode(ParentableNode parent, Exception e) { if (e instanceof KubernetesClientException kce) { if (KubernetesClientExceptionUtils.isForbidden(kce) || KubernetesClientExceptionUtils.isUnauthorized(kce)) { @@ -203,7 +203,7 @@ private MessageNode createErrorNode(ParentableNode parent, Exception e) { return new MessageNode<>(root, parent, CLUSTER_UNREACHABLE); } } - return new MessageNode<>(root, parent, "Could not get namespaces: " + ExceptionUtils.getMessage(e)); + return new MessageNode<>(root, parent, "Could not get current namespace: " + ExceptionUtils.getMessage(e)); } private List> getComponents(NamespaceNode namespaceNode, OdoFacade odo) { diff --git a/src/main/java/org/jboss/tools/intellij/openshift/utils/Cli.java b/src/main/java/org/jboss/tools/intellij/openshift/utils/Cli.java index 4857386ed..ec54da966 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/utils/Cli.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/utils/Cli.java @@ -10,6 +10,8 @@ ******************************************************************************/ package org.jboss.tools.intellij.openshift.utils; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.util.messages.MessageBus; import com.redhat.devtools.intellij.common.kubernetes.ClusterHelper; import com.redhat.devtools.intellij.common.kubernetes.ClusterInfo; import com.redhat.devtools.intellij.common.ssl.IDEATrustManager; @@ -22,13 +24,6 @@ import io.fabric8.kubernetes.client.KubernetesClientBuilder; import io.fabric8.kubernetes.client.http.HttpClient; import io.fabric8.kubernetes.client.internal.SSLUtils; -import org.jetbrains.annotations.NotNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509ExtendedTrustManager; -import javax.net.ssl.X509TrustManager; import java.io.IOException; import java.net.URISyntaxException; import java.security.KeyStoreException; @@ -42,12 +37,17 @@ import java.util.Map; import java.util.function.Function; import java.util.function.Supplier; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509ExtendedTrustManager; +import javax.net.ssl.X509TrustManager; +import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.jboss.tools.intellij.openshift.telemetry.TelemetryService.IS_OPENSHIFT; import static org.jboss.tools.intellij.openshift.telemetry.TelemetryService.KUBERNETES_VERSION; import static org.jboss.tools.intellij.openshift.telemetry.TelemetryService.NAME_PREFIX_MISC; import static org.jboss.tools.intellij.openshift.telemetry.TelemetryService.OPENSHIFT_VERSION; -import static org.jboss.tools.intellij.openshift.telemetry.TelemetryService.asyncSend; import static org.jboss.tools.intellij.openshift.telemetry.TelemetryService.instance; public class Cli { @@ -97,17 +97,27 @@ public Map apply(String url) { public static final class TelemetryReport { public void report(KubernetesClient client) { - TelemetryMessageBuilder.ActionMessage telemetry = instance().getBuilder().action(NAME_PREFIX_MISC + "login"); - try { - ClusterInfo info = ClusterHelper.getClusterInfo(client); - telemetry.property(KUBERNETES_VERSION, info.getKubernetesVersion()); - telemetry.property(IS_OPENSHIFT, Boolean.toString(info.isOpenshift())); - telemetry.property(OPENSHIFT_VERSION, info.getOpenshiftVersion()); - asyncSend(telemetry); - } catch (RuntimeException e) { - // do not send telemetry when there is no context ( ie default kube URL as master URL ) - asyncSend(telemetry.error(e)); - } + ApplicationManager.getApplication().executeOnPooledThread(() -> { + TelemetryMessageBuilder.ActionMessage telemetry = instance().getBuilder().action(NAME_PREFIX_MISC + "login"); + try { + ClusterInfo info = ClusterHelper.getClusterInfo(client); + telemetry + .property(KUBERNETES_VERSION, info.getKubernetesVersion()) + .property(IS_OPENSHIFT, Boolean.toString(info.isOpenshift())) + .property(OPENSHIFT_VERSION, info.getOpenshiftVersion()) + .send(); + } catch (RuntimeException e) { + // do not send telemetry when there is no context ( ie default kube URL as master URL ) + telemetry.error(e).send(); + } + }); + } + + public void subscribe(MessageBus bus, Map envVars) { + bus.connect().subscribe( + TelemetryConfiguration.ConfigurationChangedListener.CONFIGURATION_CHANGED, + onTelemetryConfigurationChanged(envVars) + ); } @NotNull diff --git a/src/main/java/org/jboss/tools/intellij/openshift/utils/oc/OcCli.java b/src/main/java/org/jboss/tools/intellij/openshift/utils/oc/OcCli.java index 9d8cf96e6..c07543330 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/utils/oc/OcCli.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/utils/oc/OcCli.java @@ -12,9 +12,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.util.messages.MessageBus; -import com.intellij.util.messages.MessageBusConnection; import com.redhat.devtools.intellij.common.utils.ExecHelper; -import com.redhat.devtools.intellij.telemetry.core.configuration.TelemetryConfiguration; import io.fabric8.kubernetes.client.KubernetesClient; import org.jboss.tools.intellij.openshift.utils.Cli; import org.jetbrains.annotations.NotNull; @@ -49,11 +47,13 @@ public OcCli( Cli.TelemetryReport telemetryReport) { super(kubernetesClientFactory); this.command = command; - MessageBusConnection connection = bus.connect(); this.envVars = envVarFactory.apply(String.valueOf(client.getMasterUrl())); + initTelemetry(telemetryReport, bus); + } + + private void initTelemetry(TelemetryReport telemetryReport, MessageBus bus) { telemetryReport.addTelemetryVars(envVars); - connection.subscribe(TelemetryConfiguration.ConfigurationChangedListener.CONFIGURATION_CHANGED, - telemetryReport.onTelemetryConfigurationChanged(this.envVars)); + telemetryReport.subscribe(bus, envVars); telemetryReport.report(client); } diff --git a/src/main/java/org/jboss/tools/intellij/openshift/utils/odo/OdoCli.java b/src/main/java/org/jboss/tools/intellij/openshift/utils/odo/OdoCli.java index 7dfa482e7..c54241e9a 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/utils/odo/OdoCli.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/utils/odo/OdoCli.java @@ -20,9 +20,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.util.text.Strings; import com.intellij.util.messages.MessageBus; -import com.intellij.util.messages.MessageBusConnection; import com.redhat.devtools.intellij.common.utils.ExecHelper; -import com.redhat.devtools.intellij.telemetry.core.configuration.TelemetryConfiguration; import io.fabric8.kubernetes.api.Pluralize; import io.fabric8.kubernetes.api.model.ConfigMap; import io.fabric8.kubernetes.api.model.DeletionPropagation; @@ -38,16 +36,6 @@ import io.fabric8.openshift.client.OpenShiftClient; import io.fabric8.openshift.client.dsl.OpenShiftOperatorHubAPIGroupDSL; import io.fabric8.openshift.client.impl.OpenShiftOperatorHubAPIGroupClient; -import org.apache.commons.io.FileUtils; -import org.jboss.tools.intellij.openshift.KubernetesLabels; -import org.jboss.tools.intellij.openshift.utils.Cli; -import org.jboss.tools.intellij.openshift.utils.KubernetesClientExceptionUtils; -import org.jboss.tools.intellij.openshift.utils.Serialization; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.io.BufferedReader; import java.io.File; import java.io.IOException; @@ -60,10 +48,21 @@ import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.BinaryOperator; import java.util.function.Function; import java.util.function.Supplier; +import org.apache.commons.io.FileUtils; +import org.jboss.tools.intellij.openshift.KubernetesLabels; +import org.jboss.tools.intellij.openshift.utils.Cli; +import org.jboss.tools.intellij.openshift.utils.KubernetesClientExceptionUtils; +import org.jboss.tools.intellij.openshift.utils.Serialization; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static io.fabric8.openshift.client.OpenShiftClient.BASE_API_GROUP; import static org.jboss.tools.intellij.openshift.Constants.HOME_FOLDER; @@ -93,7 +92,7 @@ public class OdoCli extends Cli implements OdoDelegate { private final AtomicBoolean swaggerLoaded = new AtomicBoolean(); private String currentNamespace; private JSonParser swagger; - private final boolean isPodmanPresent; + private CompletableFuture isPodmanPresent; public OdoCli(com.intellij.openapi.project.Project project, String command) { this(project, @@ -116,14 +115,16 @@ protected OdoCli( super(kubernetesClientFactory); this.command = command; this.project = project; - MessageBusConnection connection = bus.connect(); this.openshiftClient = openshiftClientFactory.apply(client); this.envVars = envVarFactory.apply(String.valueOf(client.getMasterUrl())); + this.isPodmanPresent = processIsPodmanPresent(command); + initTelemetry(bus, telemetryReport); + } + + private void initTelemetry(MessageBus bus, TelemetryReport telemetryReport) { telemetryReport.addTelemetryVars(envVars); - connection.subscribe(TelemetryConfiguration.ConfigurationChangedListener.CONFIGURATION_CHANGED, - telemetryReport.onTelemetryConfigurationChanged(this.envVars)); + telemetryReport.subscribe(bus, envVars); telemetryReport.report(client); - isPodmanPresent = checkPodmanPresence(); } @@ -418,7 +419,7 @@ public ComponentInfo getComponentInfo(String project, String component, String p private ComponentInfo parseComponentInfo(String json, ComponentKind kind) throws IOException { JSonParser parser = new JSonParser(Serialization.json().readTree(json)); - return parser.parseDescribeComponentInfo(kind, isPodmanPresent); + return parser.parseDescribeComponentInfo(kind, isPodmanPresent()); } /* @@ -747,21 +748,18 @@ public List getComponentTypesFromRegistry(String name) thr filter(type -> name.equals(type.getDevfileRegistry().getName())).toList(); } - private boolean checkPodmanPresence() { - CompletableFuture result = new CompletableFuture<>(); + private boolean isPodmanPresent() { try { - result.complete(ExecHelper.executeWithResult(command, false, new File(HOME_FOLDER), envVars, "version")); - return !result.get().getStdOut().contains("unable to fetch the podman client version"); + return isPodmanPresent.get(2, TimeUnit.SECONDS); } catch (InterruptedException e) { Thread.currentThread().interrupt(); LOGGER.warn(e.getLocalizedMessage(), e); - } catch (ExecutionException | IOException e) { + } catch (ExecutionException | TimeoutException e) { LOGGER.warn(e.getLocalizedMessage(), e); } return false; } - private static final class OpenShiftClientFactory implements Function { @Override public OpenShiftClient apply(KubernetesClient client) {