Skip to content

Commit

Permalink
fix: update tree, query cluster info and send telemetry in backgroud (#…
Browse files Browse the repository at this point in the history
…912) (#915)

Signed-off-by: Andre Dietisheim <[email protected]>
  • Loading branch information
adietish authored Sep 24, 2024
1 parent 8232bf8 commit 37bdd93
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<ApplicationsTreeStructure> model = new StructureTreeModel<>(structure, content);
StructureTreeModel<ApplicationsTreeStructure> 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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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<ApplicationsRootNode>, Disposable {
implements ModuleListener, ConfigWatcher.Listener, ProcessingNode, StructureAwareNode, ParentableNode<ApplicationsRootNode>, Disposable, DumbAware {

private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationsRootNode.class);
private final Project project;
Expand Down Expand Up @@ -102,7 +102,8 @@ private CompletableFuture<ApplicationRootNodeOdo> doGetOdo() {
public CompletableFuture<ApplicationRootNodeOdo> getOdo() {
return doGetOdo()
.whenComplete((ApplicationRootNodeOdo odo, Throwable err) -> {
if (odo.isDownloaded()) {
if (odo != null
&& odo.isDownloaded()) {
structure.fireModified(this);
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)) {
Expand All @@ -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<BaseNode<?>> getComponents(NamespaceNode namespaceNode, OdoFacade odo) {
Expand Down
48 changes: 29 additions & 19 deletions src/main/java/org/jboss/tools/intellij/openshift/utils/Cli.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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 {
Expand Down Expand Up @@ -97,17 +97,27 @@ public Map<String, String> 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<String, String> envVars) {
bus.connect().subscribe(
TelemetryConfiguration.ConfigurationChangedListener.CONFIGURATION_CHANGED,
onTelemetryConfigurationChanged(envVars)
);
}

@NotNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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<Boolean> isPodmanPresent;

public OdoCli(com.intellij.openapi.project.Project project, String command) {
this(project,
Expand All @@ -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 = processPodmanPresent(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();
}


Expand Down Expand Up @@ -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());
}

/*
Expand Down Expand Up @@ -747,20 +748,33 @@ public List<DevfileComponentType> getComponentTypesFromRegistry(String name) thr
filter(type -> name.equals(type.getDevfileRegistry().getName())).toList();
}

private boolean checkPodmanPresence() {
CompletableFuture<ExecHelper.ExecResult> 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");
if (isPodmanPresent == null) {
this.isPodmanPresent = processPodmanPresent(command);
}
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 @NotNull CompletableFuture<Boolean> processPodmanPresent(String command) {
return CompletableFuture
.supplyAsync(() -> {
try {
ExecHelper.ExecResult result = ExecHelper.executeWithResult(command, false, new File(HOME_FOLDER), envVars, "version");
return result.getStdOut().contains("unable to fetch the podman client version");
} catch (IOException e) {
LOGGER.warn(e.getLocalizedMessage(), e);
return false;
}
}, runnable -> ApplicationManager.getApplication().executeOnPooledThread(runnable));
}

private static final class OpenShiftClientFactory implements Function<KubernetesClient, OpenShiftClient> {
@Override
Expand Down

0 comments on commit 37bdd93

Please sign in to comment.