diff --git a/src/it/java/org/jboss/tools/intellij/openshift/utils/ToolFactoryTest.java b/src/it/java/org/jboss/tools/intellij/openshift/utils/ToolFactoryTest.java index 216181eb8..a44ab782f 100644 --- a/src/it/java/org/jboss/tools/intellij/openshift/utils/ToolFactoryTest.java +++ b/src/it/java/org/jboss/tools/intellij/openshift/utils/ToolFactoryTest.java @@ -19,12 +19,12 @@ public class ToolFactoryTest extends BasePlatformTestCase { public void testGetOdo() throws ExecutionException, InterruptedException { - Odo odo = ToolFactory.getInstance().getOdo(getProject()).get(); + Odo odo = ToolFactory.getInstance().createOdo(getProject()).get(); assertNotNull(odo); } public void testGetHelm() throws ExecutionException, InterruptedException { - Helm helm = ToolFactory.getInstance().getHelm(getProject()).get(); + Helm helm = ToolFactory.getInstance().createHelm(getProject()).get(); assertNotNull(helm); } diff --git a/src/it/java/org/jboss/tools/intellij/openshift/utils/helm/HelmCliTest.java b/src/it/java/org/jboss/tools/intellij/openshift/utils/helm/HelmCliTest.java index 8aa61a19d..c13313d36 100644 --- a/src/it/java/org/jboss/tools/intellij/openshift/utils/helm/HelmCliTest.java +++ b/src/it/java/org/jboss/tools/intellij/openshift/utils/helm/HelmCliTest.java @@ -38,7 +38,7 @@ public abstract class HelmCliTest extends BasePlatformTestCase { protected void setUp() throws Exception { super.setUp(); this.previousTestDialog = MessagesHelper.setTestDialog(TestDialog.OK); - this.helm = ToolFactory.getInstance().getHelm(getProject()).get(); + this.helm = ToolFactory.getInstance().createHelm(getProject()).get(); } @Override diff --git a/src/it/java/org/jboss/tools/intellij/openshift/utils/odo/OdoCliTest.java b/src/it/java/org/jboss/tools/intellij/openshift/utils/odo/OdoCliTest.java index bf56ba28d..e69204d73 100644 --- a/src/it/java/org/jboss/tools/intellij/openshift/utils/odo/OdoCliTest.java +++ b/src/it/java/org/jboss/tools/intellij/openshift/utils/odo/OdoCliTest.java @@ -61,13 +61,13 @@ public abstract class OdoCliTest extends BasePlatformTestCase { protected void setUp() throws Exception { super.setUp(); previousTestDialog = MessagesHelper.setTestDialog(TestDialog.OK); - odo = ToolFactory.getInstance().getOdo(getProject()).get(); + odo = ToolFactory.getInstance().createOdo(getProject()).get(); if (odo.listDevfileRegistries().stream().noneMatch(c -> c.getName().equals(REGISTRY_NAME))) odo.createDevfileRegistry(REGISTRY_NAME, REGISTRY_URL, null); if (CLUSTER_URL != null && !odo.getMasterUrl().toString().startsWith(CLUSTER_URL)) { odo.login(CLUSTER_URL, CLUSTER_USER, CLUSTER_PASSWORD.toCharArray(), null); - odo = ToolFactory.getInstance().getOdo(getProject()).get(); + odo = ToolFactory.getInstance().createOdo(getProject()).get(); } } @@ -81,8 +81,8 @@ protected void tearDown() throws Exception { protected void createProject(String project) throws IOException, ExecutionException, InterruptedException { odo.createProject(project); // need to refresh kubernetes client with the correct namespace - ToolFactory.getInstance().resetOdo(); - odo = ToolFactory.getInstance().getOdo(getProject()).get(); + //resetOdo(); + odo = ToolFactory.getInstance().createOdo(getProject()).get(); } protected void createComponent(String project, String component, ComponentFeature feature) throws IOException, ExecutionException, InterruptedException { diff --git a/src/main/java/org/jboss/tools/intellij/openshift/actions/NodeUtils.java b/src/main/java/org/jboss/tools/intellij/openshift/actions/NodeUtils.java index c6518fad0..44da8d05e 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/actions/NodeUtils.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/actions/NodeUtils.java @@ -10,10 +10,15 @@ ******************************************************************************/ package org.jboss.tools.intellij.openshift.actions; +import com.intellij.ide.util.treeView.NodeDescriptor; +import org.jboss.tools.intellij.openshift.tree.application.ApplicationsRootNode; import org.jboss.tools.intellij.openshift.tree.application.ComponentNode; +import org.jboss.tools.intellij.openshift.tree.application.ParentableNode; import org.jboss.tools.intellij.openshift.tree.application.ProcessingNode; import org.jboss.tools.intellij.openshift.tree.application.StructureAwareNode; +import javax.swing.tree.DefaultMutableTreeNode; + public class NodeUtils { private NodeUtils() { @@ -55,4 +60,23 @@ public static void fireModified(StructureAwareNode node) { public static void fireRemoved(StructureAwareNode node) { node.getStructure().fireRemoved(node); } + + public static ApplicationsRootNode getRoot(Object selected) { + ProcessingNode node = getElement(selected); + if (!(node instanceof ParentableNode)) { + return null; + } + return ((ParentableNode) node).getRoot(); + } + + public static T getElement(Object selected) { + if (selected instanceof DefaultMutableTreeNode) { + selected = ((DefaultMutableTreeNode)selected).getUserObject(); + } + if (selected instanceof NodeDescriptor) { + selected = ((NodeDescriptor)selected).getElement(); + } + return (T) selected; + } + } diff --git a/src/main/java/org/jboss/tools/intellij/openshift/actions/cluster/RefreshAction.java b/src/main/java/org/jboss/tools/intellij/openshift/actions/cluster/RefreshAction.java index 700ab9efb..ac20e0801 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/actions/cluster/RefreshAction.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/actions/cluster/RefreshAction.java @@ -10,18 +10,18 @@ ******************************************************************************/ package org.jboss.tools.intellij.openshift.actions.cluster; +import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.progress.ProgressIndicator; import com.redhat.devtools.intellij.common.actions.StructureTreeAction; +import org.jboss.tools.intellij.openshift.actions.NodeUtils; import org.jboss.tools.intellij.openshift.telemetry.TelemetryService; import org.jboss.tools.intellij.openshift.tree.application.ApplicationsRootNode; -import org.jboss.tools.intellij.openshift.tree.application.ProcessingNode; +import org.jboss.tools.intellij.openshift.tree.application.ParentableNode; import javax.swing.tree.TreePath; import static org.jboss.tools.intellij.openshift.actions.ActionUtils.runWithProgress; -import static org.jboss.tools.intellij.openshift.actions.NodeUtils.clearProcessing; -import static org.jboss.tools.intellij.openshift.actions.NodeUtils.setProcessing; import static org.jboss.tools.intellij.openshift.telemetry.TelemetryService.PREFIX_ACTION; public class RefreshAction extends StructureTreeAction { @@ -29,18 +29,28 @@ public RefreshAction() { super(ApplicationsRootNode.class); } + public static void execute(ParentableNode node) { + RefreshAction action = (RefreshAction) ActionManager.getInstance().getAction(RefreshAction.class.getName()); + action.doActionPerformed(node.getRoot()); + } + @Override public void actionPerformed(AnActionEvent anActionEvent, TreePath path, Object selected) { + doActionPerformed(NodeUtils.getRoot(selected)); + } + + public void doActionPerformed(ApplicationsRootNode root) { + if (root == null) { + return; + } runWithProgress((ProgressIndicator progress) -> { - ProcessingNode node = getElement(selected); - setProcessing("Refreshing ", node); + root.refresh(); TelemetryService.instance().getBuilder() .action(PREFIX_ACTION + "refresh cluster") .success() .send(); - clearProcessing(node); }, - "Refresh...", - getEventProject(anActionEvent)); + "Refreshing...", + root.getProject()); } } diff --git a/src/main/java/org/jboss/tools/intellij/openshift/actions/component/CreateComponentAction.java b/src/main/java/org/jboss/tools/intellij/openshift/actions/component/CreateComponentAction.java index a053aaa45..d5ee8336f 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/actions/component/CreateComponentAction.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/actions/component/CreateComponentAction.java @@ -67,7 +67,7 @@ public static void execute(ParentableNode parentNode) { @Override public void actionPerformed(AnActionEvent anActionEvent, Object selected, @NotNull Odo odo) { NamespaceNode namespaceNode = ((NamespaceNode) selected); - ApplicationsRootNode rootNode = ((ParentableNode) selected).getRoot(); + ApplicationsRootNode rootNode = namespaceNode.getRoot(); Project project = rootNode.getProject(); doActionPerformed((NamespaceNode) selected, odo, namespaceNode.getName(), rootNode, project); } diff --git a/src/main/java/org/jboss/tools/intellij/openshift/actions/component/LinkServiceAction.java b/src/main/java/org/jboss/tools/intellij/openshift/actions/component/LinkServiceAction.java index 74a049e37..883f1df8d 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/actions/component/LinkServiceAction.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/actions/component/LinkServiceAction.java @@ -21,9 +21,9 @@ import com.redhat.devtools.intellij.common.utils.UIHelper; import org.jboss.tools.intellij.openshift.actions.NodeUtils; import org.jboss.tools.intellij.openshift.actions.OdoAction; +import org.jboss.tools.intellij.openshift.tree.application.BaseNode; import org.jboss.tools.intellij.openshift.tree.application.ComponentNode; import org.jboss.tools.intellij.openshift.tree.application.NamespaceNode; -import org.jboss.tools.intellij.openshift.tree.application.ParentableNode; import org.jboss.tools.intellij.openshift.ui.binding.BindingDetailDialog; import org.jboss.tools.intellij.openshift.utils.odo.Binding; import org.jboss.tools.intellij.openshift.utils.odo.Component; @@ -99,7 +99,7 @@ private static String getServiceName(List services) { null)); } - private void linkService(Service service, Component component, ParentableNode namespaceNode, Odo odo, Project project) throws IOException { + private void linkService(Service service, Component component, BaseNode namespaceNode, Odo odo, Project project) throws IOException { Notification notification = notify("Linking component to service " + service.getName()); String target = service.getName() + '/' + service.getKind() + "." + service.getApiVersion(); Binding binding = odo.link(namespaceNode.getName(), component.getPath(), component.getName(), target); 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 66a72cd35..9eab203a2 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 @@ -25,9 +25,7 @@ import com.redhat.devtools.intellij.common.utils.ConfigWatcher; import com.redhat.devtools.intellij.common.utils.ExecHelper; import io.fabric8.kubernetes.api.model.Config; -import io.fabric8.kubernetes.api.model.NamedContext; -import io.fabric8.kubernetes.client.internal.KubeConfigUtils; -import org.apache.commons.codec.binary.StringUtils; +import org.jboss.tools.intellij.openshift.ui.SwingUtils; import org.jboss.tools.intellij.openshift.utils.ProjectUtils; import org.jboss.tools.intellij.openshift.utils.ToolFactory; import org.jboss.tools.intellij.openshift.utils.helm.Helm; @@ -44,10 +42,12 @@ import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; +import java.util.function.BiConsumer; import static org.jboss.tools.intellij.openshift.Constants.GROUP_DISPLAY_ID; -public class ApplicationsRootNode implements ModuleListener, ConfigWatcher.Listener, StructureAwareNode, ProcessingNode { +public class ApplicationsRootNode + implements ModuleListener, ConfigWatcher.Listener, ProcessingNode, StructureAwareNode, ParentableNode { private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationsRootNode.class); private final Project project; @@ -65,7 +65,7 @@ public ApplicationsRootNode(Project project, ApplicationsTreeStructure structure this.project = project; this.structure = structure; initConfigWatcher(); - config = loadConfig(); + this.config = loadConfig(); registerProjectListener(project); } @@ -77,31 +77,34 @@ public void setLogged(boolean logged) { this.logged = logged; } - public CompletableFuture getOdo() { - return getOdo(true); - } - - public CompletableFuture getOdo(boolean notify) { + private CompletableFuture getOdo(BiConsumer whenComplete) { if (odoFuture == null) { this.odoFuture = ToolFactory.getInstance() - .getOdo(project) + .createOdo(project) .thenApply(odo -> (Odo) new ApplicationRootNodeOdo(odo, this)) - .whenComplete((odo, err) -> { - loadProjectModel(odo, project); - if (notify) { - structure.fireModified(this); - } - }); + .whenComplete((odo, err) -> loadProjectModel(odo, project)) + .whenComplete(whenComplete); } return odoFuture; } + public CompletableFuture getOdo() { + return getOdo((odo, err) -> structure.fireModified(this)); + } + + public void resetOdo() { + this.odoFuture = null; + } + public CompletableFuture getHelm(boolean notify) { if (helmFuture == null) { this.helmFuture = ToolFactory.getInstance() - .getHelm(project) - .whenComplete((odo, err) -> - structure.fireModified(this) + .createHelm(project) + .whenComplete((odo, err) -> { + if (notify) { + structure.fireModified(this); + } + } ); } return helmFuture; @@ -222,46 +225,20 @@ protected void registerProjectListener(Project project) { @Override public void onUpdate(ConfigWatcher source, Config config) { - if (hasContextChanged(config, this.config)) { + if (!ConfigHelper.areEqual(config, this.config)) { + this.config = config; refresh(); } - this.config = config; - } - - private boolean hasContextChanged(Config newConfig, Config currentConfig) { - NamedContext currentContext = KubeConfigUtils.getCurrentContext(currentConfig); - NamedContext newContext = KubeConfigUtils.getCurrentContext(newConfig); - return hasServerChanged(newContext, currentContext) - || hasNewToken(newContext, newConfig, currentContext, currentConfig); - } - - private boolean hasServerChanged(NamedContext newContext, NamedContext currentContext) { - return newContext == null - || currentContext == null - || !StringUtils.equals(currentContext.getContext().getCluster(), newContext.getContext().getCluster()) - || !StringUtils.equals(currentContext.getContext().getUser(), newContext.getContext().getUser()) - || !StringUtils.equals(currentContext.getContext().getNamespace(), newContext.getContext().getNamespace()); - } - - private boolean hasNewToken(NamedContext newContext, Config newConfig, NamedContext currentContext, Config currentConfig) { - if (newContext == null) { - return false; - } - if (currentContext == null) { - return true; - } - String newToken = KubeConfigUtils.getUserToken(newConfig, newContext.getContext()); - if (newToken == null) { - // logout, do not refresh, LogoutAction already refreshes - return false; - } - String currentToken = KubeConfigUtils.getUserToken(currentConfig, currentContext.getContext()); - return !StringUtils.equals(newToken, currentToken); } - public void refresh() { - ToolFactory.getInstance().resetOdo(); - getOdo().thenAccept(odo -> structure.fireModified(this)); + public synchronized void refresh() { + resetOdo(); + CompletableFuture + .runAsync(() -> + getOdo((odo, err) -> { + structure.fireModified(ApplicationsRootNode.this); + }), + SwingUtils.EXECUTOR_BACKGROUND); } @Override @@ -270,28 +247,37 @@ public ApplicationsTreeStructure getStructure() { } @Override - public void startProcessing(String message) { + public synchronized void startProcessing(String message) { this.processingNode.startProcessing(message); } @Override - public void stopProcessing() { + public synchronized void stopProcessing() { this.processingNode.stopProcessing(); } @Override - public boolean isProcessing() { + public synchronized boolean isProcessing() { return processingNode.isProcessing(); } @Override - public boolean isProcessingStopped() { + public synchronized boolean isProcessingStopped() { return processingNode.isProcessingStopped(); } @Override - public String getProcessingMessage() { + public String getMessage() { return processingNode.getMessage(); } + @Override + public ApplicationsRootNode getParent() { + return this; + } + + @Override + public ApplicationsRootNode getRoot() { + return 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 7acba9cc3..3437d379f 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 @@ -14,6 +14,7 @@ import com.intellij.ide.util.treeView.AbstractTreeStructure; import com.intellij.ide.util.treeView.NodeDescriptor; import com.intellij.openapi.project.Project; +import com.intellij.ui.tree.LeafState; import com.redhat.devtools.intellij.common.tree.LabelAndIconDescriptor; import com.redhat.devtools.intellij.common.tree.MutableModel; import com.redhat.devtools.intellij.common.tree.MutableModelSupport; @@ -69,9 +70,8 @@ public Object getApplicationsRoot() { public Object @NotNull [] getChildElements(@NotNull Object element) { if (element == this) { return new Object[]{getApplicationsRoot(), registries}; - } - if (element instanceof ApplicationsRootNode) { - return getNamespaces((ApplicationsRootNode) element); + } else if (element instanceof ApplicationsRootNode) { + return getCurrentNamespace((ApplicationsRootNode) element); } else if (element instanceof NamespaceNode) { return createNamespaceChildren((NamespaceNode) element); } else if (element instanceof ComponentNode) { @@ -86,6 +86,19 @@ public Object getApplicationsRoot() { return new Object[0]; } + @Override + public @NotNull LeafState getLeafState(@NotNull Object element) { + if (element instanceof ComponentNode) { + return LeafState.ALWAYS; + } else if (element instanceof ChartReleaseNode) { + return LeafState.ALWAYS; + } else if (element instanceof MessageNode) { + return LeafState.ALWAYS; + } else { + return LeafState.ASYNC; + } + } + @NotNull private Object[] createComponentChildren(ComponentNode element) { List urls = getURLs(element); @@ -110,45 +123,45 @@ private Object[] createNamespaceChildren(@NotNull NamespaceNode namespaceNode) { return nodes.toArray(); } - private Object[] getNamespaces(ApplicationsRootNode element) { + private Object[] getCurrentNamespace(ApplicationsRootNode element) { List namespaces = new ArrayList<>(); try { Odo odo = element.getOdo().getNow(null); - if (odo == null) { - return new Object[]{}; - } - String ns = odo.getNamespace(); - if (ns != null) { - namespaces.add(new NamespaceNode(element, odo.getNamespace())); - } else { - namespaces.add(new CreateNamespaceLinkNode(element)); - } - element.setLogged(true); - } catch (Exception e) { - if (e instanceof KubernetesClientException) { - KubernetesClientException kce = (KubernetesClientException) e; - if (kce.getCode() == 401) { - namespaces.add(new MessageNode<>(element, element, LOGIN)); - } else if (kce.getCause() instanceof NoRouteToHostException) { - namespaces.add(new MessageNode<>(element, element, kce.getCause().getMessage())); - } else if (kce.getCause().getMessage().contains(Constants.DEFAULT_KUBE_URL)) { - namespaces.add(new MessageNode<>(element, element, LOGIN)); + if (odo != null) { + String ns = odo.getNamespace(); + if (ns != null) { + namespaces.add(new NamespaceNode(element, odo.getNamespace())); } else { - namespaces.add(new MessageNode<>(element, element, "Unable to get namespaces: " + e.getMessage())); + namespaces.add(new CreateNamespaceLinkNode(element)); } - } else { - namespaces.add(new MessageNode<>(element, element, "Unable to get namespaces: " + e.getMessage())); + element.setLogged(true); } + } catch (Exception e) { + namespaces.add(createErrorNode(element, e)); element.setLogged(false); } return namespaces.toArray(); } - private List> getComponents(NamespaceNode element, Odo odo) { + private static MessageNode createErrorNode(ApplicationsRootNode element, Exception e) { + if (e instanceof KubernetesClientException) { + KubernetesClientException kce = (KubernetesClientException) e; + if (kce.getCode() == 401) { + return new MessageNode<>(element, element, LOGIN); + } else if (kce.getCause() instanceof NoRouteToHostException) { + return new MessageNode<>(element, element, kce.getCause().getMessage()); + } else if (kce.getCause().getMessage().contains(Constants.DEFAULT_KUBE_URL)) { + return new MessageNode<>(element, element, LOGIN); + } + } + return new MessageNode<>(element, element, "Unable to get namespaces: " + e.getMessage()); + } + + private List> getComponents(NamespaceNode element, Odo odo) { if (odo == null) { return Collections.emptyList(); } - List> components = new ArrayList<>(); + List> components = new ArrayList<>(); components.addAll(load( () -> odo.getComponents(element.getName()).stream() .filter(component -> !component.isManagedByHelm()) // dont display helm components @@ -162,7 +175,7 @@ private List> getComponents(NamespaceNode element, Odo odo) { return components; } - private List> getServices(NamespaceNode element, Odo odo) { + private List> getServices(NamespaceNode element, Odo odo) { if (odo == null) { return Collections.emptyList(); } @@ -173,7 +186,7 @@ private List> getServices(NamespaceNode element, Odo odo) { "Failed to load application services"); } - private List> getHelmReleases(NamespaceNode element, Helm helm) { + private List> getHelmReleases(NamespaceNode element, Helm helm) { if (helm == null) { return Collections.emptyList(); } @@ -184,7 +197,7 @@ private List> getHelmReleases(NamespaceNode element, Helm helm "Failed to load chart releases"); } - private List> load(Callable>> callable, NamespaceNode namespace, String errorMessage) { + private List> load(Callable>> callable, NamespaceNode namespace, String errorMessage) { try { return callable.call(); } catch (Exception e) { @@ -274,12 +287,12 @@ private Object[] getRegistryComponentTypeStarters(DevfileRegistryComponentTypeNo @Override public Object getParentElement(@NotNull Object element) { - if (element instanceof ParentableNode) { - return ((ParentableNode) element).getParent(); - } if (element instanceof ApplicationsRootNode) { return this; } + if (element instanceof ParentableNode) { + return ((ParentableNode) element).getParent(); + } return null; } @@ -330,34 +343,34 @@ public ProcessableDescriptor(Project project, T element, Supplier label, @Override protected void update(@NotNull PresentationData presentation) { - super.update(presentation); if (isProcessing()) { String processingLabel = getProcessingMessage(); if (processingLabel != null) { presentation.setLocationString(processingLabel); } } + super.update(presentation); } private String getProcessingMessage() { - ParentableNode modelNode = getParentableNode(); - if (modelNode != null) { - return modelNode.getProcessingMessage(); + ProcessingNode node = getProcessingNode(); + if (node != null) { + return node.getMessage(); } else { return null; } } private boolean isProcessing() { - ParentableNode node = getParentableNode(); + ProcessingNode node = getProcessingNode(); return node != null && node.isProcessing(); } - private ParentableNode getParentableNode() { + private ProcessingNode getProcessingNode() { Object element = getElement(); - if (element instanceof ParentableNode) { - return (ParentableNode) element; + if (element instanceof ProcessingNode) { + return (ProcessingNode) element; } else { return null; } diff --git a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/BaseNode.java b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/BaseNode.java new file mode 100644 index 000000000..66fb7d969 --- /dev/null +++ b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/BaseNode.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2021 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package org.jboss.tools.intellij.openshift.tree.application; + +public abstract class BaseNode implements ProcessingNode, StructureAwareNode, ParentableNode { + private final T parent; + private final ApplicationsRootNode root; + private final String name; + private final ProcessingNodeImpl processingNode = new ProcessingNodeImpl(); + + protected BaseNode(ApplicationsRootNode root, T parent, String name) { + this.root = root; + this.parent = parent; + this.name = name; + } + + @Override + public ApplicationsRootNode getRoot() { + return root; + } + + @Override + public T getParent() { + return parent; + } + + public String getName() { + return name; + } + + public String getNamespace() { + Object node = getNamespaceNode(this); + if (node instanceof NamespaceNode) { + return ((NamespaceNode)node).getName(); + } else { + return ""; + } + } + + private static Object getNamespaceNode(Object node) { + while (!(node instanceof NamespaceNode)) { + if (node instanceof ParentableNode) { + node = ((ParentableNode) node).getParent(); + } + if (node == null){ + return null; + } + } + return node; + } + + @Override + public ApplicationsTreeStructure getStructure() { + return getRoot().getStructure(); + } + + @Override + public void startProcessing(String message) { + this.processingNode.startProcessing(message); + } + + @Override + public void stopProcessing() { + this.processingNode.stopProcessing(); + } + + @Override + public boolean isProcessing() { + return processingNode.isProcessing(); + } + + @Override + public boolean isProcessingStopped() { + return processingNode.isProcessingStopped(); + } + + @Override + public String getMessage() { + return processingNode.getMessage(); + } + +} diff --git a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/BindingNode.java b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/BindingNode.java index 2ed87ee00..22676ec29 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/BindingNode.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/BindingNode.java @@ -12,7 +12,7 @@ import org.jboss.tools.intellij.openshift.utils.odo.Binding; -public class BindingNode extends ParentableNode { +public class BindingNode extends BaseNode { private final Binding binding; public BindingNode(ComponentNode parent, Binding binding) { diff --git a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ChartReleaseNode.java b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ChartReleaseNode.java index 25893499f..b3fe91142 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ChartReleaseNode.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ChartReleaseNode.java @@ -12,7 +12,7 @@ import org.jboss.tools.intellij.openshift.utils.helm.ChartRelease; -public class ChartReleaseNode extends ParentableNode { +public class ChartReleaseNode extends BaseNode { private final ChartRelease release; public ChartReleaseNode(NamespaceNode parent, ChartRelease release) { diff --git a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ComponentNode.java b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ComponentNode.java index 1497056c4..544dca634 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ComponentNode.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ComponentNode.java @@ -12,7 +12,7 @@ import org.jboss.tools.intellij.openshift.utils.odo.Component; -public class ComponentNode extends ParentableNode { +public class ComponentNode extends BaseNode { private final Component component; public ComponentNode(NamespaceNode parent, Component component) { diff --git a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/CreateComponentLinkNode.java b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/CreateComponentLinkNode.java index 849d629a3..38a6799fb 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/CreateComponentLinkNode.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/CreateComponentLinkNode.java @@ -13,8 +13,8 @@ import com.redhat.devtools.intellij.common.tree.LinkElement; import org.jboss.tools.intellij.openshift.actions.component.CreateComponentAction; -public class CreateComponentLinkNode extends MessageNode> implements LinkElement { - protected CreateComponentLinkNode(ApplicationsRootNode root, ParentableNode parent) { +public class CreateComponentLinkNode extends MessageNode> implements LinkElement { + protected CreateComponentLinkNode(ApplicationsRootNode root, BaseNode parent) { super(root, parent, "No deployments, click here to create one."); } diff --git a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/DescriptorFactory.java b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/DescriptorFactory.java index ded53e0dd..e834e16a8 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/DescriptorFactory.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/DescriptorFactory.java @@ -51,13 +51,12 @@ public class DescriptorFactory { project, root, () -> { - String label = "Loading..."; try { Odo odo = root.getOdo().getNow(null); - if (odo != null) { - label = odo.getMasterUrl().toString(); + if (odo == null) { + return "Loading..."; } - return label; + return odo.getMasterUrl().toString(); } catch (Exception e) { return "Error: " + e.getCause().getMessage(); } diff --git a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/DevfileRegistriesNode.java b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/DevfileRegistriesNode.java index 06da9f270..6826e70ff 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/DevfileRegistriesNode.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/DevfileRegistriesNode.java @@ -10,7 +10,7 @@ ******************************************************************************/ package org.jboss.tools.intellij.openshift.tree.application; -public class DevfileRegistriesNode extends ParentableNode { +public class DevfileRegistriesNode extends BaseNode { public DevfileRegistriesNode(ApplicationsRootNode root) { super(root, null, ""); diff --git a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/DevfileRegistryComponentTypeNode.java b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/DevfileRegistryComponentTypeNode.java index df111f3c0..fd854e12f 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/DevfileRegistryComponentTypeNode.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/DevfileRegistryComponentTypeNode.java @@ -12,7 +12,7 @@ import org.jboss.tools.intellij.openshift.utils.odo.DevfileComponentType; -public class DevfileRegistryComponentTypeNode extends ParentableNode { +public class DevfileRegistryComponentTypeNode extends BaseNode { private final DevfileComponentType componentType; public DevfileRegistryComponentTypeNode(ApplicationsRootNode root, DevfileRegistryNode parent, DevfileComponentType componentType) { diff --git a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/DevfileRegistryComponentTypeStarterNode.java b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/DevfileRegistryComponentTypeStarterNode.java index c1f7c799b..8c3f53f71 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/DevfileRegistryComponentTypeStarterNode.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/DevfileRegistryComponentTypeStarterNode.java @@ -12,7 +12,7 @@ import org.jboss.tools.intellij.openshift.utils.odo.Starter; -public class DevfileRegistryComponentTypeStarterNode extends ParentableNode { +public class DevfileRegistryComponentTypeStarterNode extends BaseNode { private final Starter starter; public DevfileRegistryComponentTypeStarterNode(ApplicationsRootNode root, DevfileRegistryComponentTypeNode parent, Starter starter) { diff --git a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/DevfileRegistryNode.java b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/DevfileRegistryNode.java index 26f8f4dd5..85c10314a 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/DevfileRegistryNode.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/DevfileRegistryNode.java @@ -12,7 +12,7 @@ import org.jboss.tools.intellij.openshift.utils.odo.DevfileRegistry; -public class DevfileRegistryNode extends ParentableNode { +public class DevfileRegistryNode extends BaseNode { private final DevfileRegistry registry; public DevfileRegistryNode(ApplicationsRootNode root, DevfileRegistriesNode parent, DevfileRegistry registry) { diff --git a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/MessageNode.java b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/MessageNode.java index a8ed49507..ce7975f40 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/MessageNode.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/MessageNode.java @@ -10,7 +10,7 @@ ******************************************************************************/ package org.jboss.tools.intellij.openshift.tree.application; -public class MessageNode extends ParentableNode { +public class MessageNode extends BaseNode { protected MessageNode(ApplicationsRootNode root, T parent, String name) { super(root, parent, name); } diff --git a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/NamespaceNode.java b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/NamespaceNode.java index 0740818ee..96e52287a 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/NamespaceNode.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/NamespaceNode.java @@ -10,7 +10,7 @@ ******************************************************************************/ package org.jboss.tools.intellij.openshift.tree.application; -public class NamespaceNode extends ParentableNode { +public class NamespaceNode extends BaseNode { public NamespaceNode(ApplicationsRootNode parent, String name) { super(parent, parent, name); } diff --git a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ParentableNode.java b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ParentableNode.java index 32fb88db5..eea1728a0 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ParentableNode.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ParentableNode.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2021 Red Hat, Inc. + * Copyright (c) 2023 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v2.0 which accompanies this distribution, @@ -10,79 +10,9 @@ ******************************************************************************/ package org.jboss.tools.intellij.openshift.tree.application; -public abstract class ParentableNode implements ProcessingNode, StructureAwareNode { - private final T parent; - private final ApplicationsRootNode root; - private final String name; - private final ProcessingNodeImpl processingNode = new ProcessingNodeImpl(); +public interface ParentableNode { - protected ParentableNode(ApplicationsRootNode root, T parent, String name) { - this.root = root; - this.parent = parent; - this.name = name; - } - - public ApplicationsRootNode getRoot() { - return root; - } - - public T getParent() { - return parent; - } - - public String getName() { - return name; - } - - public String getNamespace() { - Object node = getNamespaceNode(this); - if (node instanceof NamespaceNode) { - return ((NamespaceNode)node).getName(); - } else { - return ""; - } - } - - private static Object getNamespaceNode(Object node) { - while (!(node instanceof NamespaceNode)) { - if (node instanceof ParentableNode) { - node = ((ParentableNode) node).getParent(); - } - if (node == null){ - return null; - } - } - return node; - } - - @Override - public ApplicationsTreeStructure getStructure() { - return getRoot().getStructure(); - } - - @Override - public void startProcessing(String message) { - this.processingNode.startProcessing(message); - } - - @Override - public void stopProcessing() { - this.processingNode.stopProcessing(); - } - - @Override - public boolean isProcessing() { - return processingNode.isProcessing(); - } - - @Override - public boolean isProcessingStopped() { - return processingNode.isProcessingStopped(); - } - - @Override - public String getProcessingMessage() { - return processingNode.getMessage(); - } + T getParent(); + ApplicationsRootNode getRoot(); } diff --git a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ProcessingNode.java b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ProcessingNode.java index 0813ca512..197bd96f2 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ProcessingNode.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ProcessingNode.java @@ -10,7 +10,7 @@ ******************************************************************************/ package org.jboss.tools.intellij.openshift.tree.application; -public interface ProcessingNode extends StructureAwareNode { +public interface ProcessingNode { void startProcessing(String message); @@ -20,7 +20,7 @@ public interface ProcessingNode extends StructureAwareNode { boolean isProcessingStopped(); - String getProcessingMessage(); + String getMessage(); class ProcessingNodeImpl { diff --git a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ServiceNode.java b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ServiceNode.java index b4b1c836f..65ddf4086 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ServiceNode.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/ServiceNode.java @@ -12,7 +12,7 @@ import org.jboss.tools.intellij.openshift.utils.odo.Service; -public class ServiceNode extends ParentableNode { +public class ServiceNode extends BaseNode { private final Service service; diff --git a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/URLNode.java b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/URLNode.java index 6e83387d8..4fd676373 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/tree/application/URLNode.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/tree/application/URLNode.java @@ -12,7 +12,7 @@ import org.jboss.tools.intellij.openshift.utils.odo.URL; -public class URLNode extends ParentableNode { +public class URLNode extends BaseNode { private final URL url; public URLNode(ComponentNode parent, URL url) { diff --git a/src/main/java/org/jboss/tools/intellij/openshift/utils/ToolFactory.java b/src/main/java/org/jboss/tools/intellij/openshift/utils/ToolFactory.java index f21062e25..6d3dcfa02 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/utils/ToolFactory.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/utils/ToolFactory.java @@ -40,20 +40,12 @@ public static ToolFactory getInstance() { private ToolFactory() { } - public CompletableFuture getOdo(Project project) { - return odo.get(project); + public CompletableFuture createOdo(Project project) { + return odo.create(project); } - public void resetOdo() { - this.odo.reset(); - } - - public CompletableFuture getHelm(Project project) { - return helm.get(project); - } - - public void resetHelm() { - this.helm.reset(); + public CompletableFuture createHelm(Project project) { + return helm.create(project); } private static class Tool { @@ -62,18 +54,13 @@ private static class Tool { private final BiFunction toolFactory; - private CompletableFuture factory = null; - private Tool(String name, BiFunction toolFactory) { this.name = name; this.toolFactory = toolFactory; } - private CompletableFuture get(Project project) { - if (factory == null) { - this.factory = create(name, toolFactory, project); - } - return factory; + private CompletableFuture create(Project project) { + return create(name, toolFactory, project); } private CompletableFuture create(String name, BiFunction toolFactory, Project project) { @@ -87,9 +74,5 @@ private CompletableFuture create(String name, BiFunction } }); } - - private void reset() { - this.factory = null; - } } } 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 73e8a32f3..625325bbf 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 @@ -33,16 +33,18 @@ import io.fabric8.kubernetes.api.model.ConfigMap; import io.fabric8.kubernetes.api.model.DeletionPropagation; import io.fabric8.kubernetes.api.model.GenericKubernetesResource; -import io.fabric8.kubernetes.api.model.Namespace; +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.fabric8.kubernetes.api.model.KubernetesResourceList; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.KubernetesClientBuilder; import io.fabric8.kubernetes.client.KubernetesClientException; import io.fabric8.kubernetes.client.VersionInfo; +import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation; +import io.fabric8.kubernetes.client.dsl.Resource; import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext; import io.fabric8.kubernetes.client.http.HttpRequest; import io.fabric8.kubernetes.client.http.HttpResponse; import io.fabric8.kubernetes.model.Scope; -import io.fabric8.openshift.api.model.Project; import io.fabric8.openshift.client.OpenShiftClient; import io.fabric8.openshift.client.dsl.OpenShiftOperatorHubAPIGroupDSL; import io.fabric8.openshift.client.impl.OpenShiftOperatorHubAPIGroupClient; @@ -214,29 +216,34 @@ protected String validateNamespace(String ns) { if (Strings.isNullOrEmpty(ns)) { ns = "default"; } + boolean isOpenShift = isOpenShift(); try { - if (isOpenShift()) { + if (isOpenShift) { client.adapt(OpenShiftClient.class).projects().withName(ns).get(); } else { client.namespaces().withName(ns).get(); } } catch (KubernetesClientException e) { - ns = ""; - if (isOpenShift()) { - List projects = client.adapt(OpenShiftClient.class).projects().list().getItems(); - if (!projects.isEmpty()) { - ns = projects.get(0).getMetadata().getName(); - } + // namespace with name ns not found + if (isOpenShift) { + ns = getFirst(client.adapt(OpenShiftClient.class).projects()); } else { - List namespaces = client.namespaces().list().getItems(); - if (!namespaces.isEmpty()) { - ns = namespaces.get(0).getMetadata().getName(); - } + ns = getFirst(client.adapt(OpenShiftClient.class).namespaces()); } } + return ns; } + private String getFirst(NonNamespaceOperation, ? extends Resource> operation) { + String name = ""; + List resources = operation.list().getItems(); + if (!resources.isEmpty()) { + name = resources.get(0).getMetadata().getName(); + } + return name; + } + @Override public String getNamespace() { if (namespace == null) { diff --git a/src/test/java/org/jboss/tools/intellij/openshift/tree/application/ApplicationTreeModelConfigUpdateTest.java b/src/test/java/org/jboss/tools/intellij/openshift/tree/application/ApplicationTreeModelConfigUpdateTest.java index 798c74d36..97e7b4e32 100644 --- a/src/test/java/org/jboss/tools/intellij/openshift/tree/application/ApplicationTreeModelConfigUpdateTest.java +++ b/src/test/java/org/jboss/tools/intellij/openshift/tree/application/ApplicationTreeModelConfigUpdateTest.java @@ -135,8 +135,7 @@ protected Config loadConfig() { } @Override - public synchronized void refresh() { - } + public synchronized void refresh() {} }); }