/** * Copyright 2014 Microsoft Open Technologies Inc. * * 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 com.microsoftopentechnologies.intellij.serviceexplorer.azure.vm; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.SettableFuture; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; import com.microsoftopentechnologies.intellij.helpers.UIHelper; import com.microsoftopentechnologies.intellij.helpers.azure.AzureCmdException; import com.microsoftopentechnologies.intellij.helpers.azure.sdk.AzureSDKManagerImpl; import com.microsoftopentechnologies.intellij.model.vm.Endpoint; import com.microsoftopentechnologies.intellij.model.vm.VirtualMachine; import com.microsoftopentechnologies.intellij.serviceexplorer.*; import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.io.File; import java.io.FileOutputStream; import java.util.List; import java.util.Map; public class VMNode extends Node { private static final String WAIT_ICON_PATH = "virtualmachinewait.png"; private static final String STOP_ICON_PATH = "virtualmachinestop.png"; private static final String RUN_ICON_PATH = "virtualmachinerun.png"; private static final String VM_STATUS_RUNNING = "Running"; private static final String VM_STATUS_SUSPENDED = "Suspended"; public static final String ACTION_DELETE = "Delete"; public static final String ACTION_DOWNLOAD_RDP_FILE = "Connect Remote Desktop"; public static final String ACTION_SHUTDOWN = "Shutdown"; public static final String ACTION_START = "Start"; public static final String ACTION_RESTART = "Restart"; protected VirtualMachine virtualMachine; public VMNode(Node parent, VirtualMachine virtualMachine) throws AzureCmdException { super(virtualMachine.getName(), virtualMachine.getName(), parent, WAIT_ICON_PATH, true); this.virtualMachine = virtualMachine; // update vm icon based on vm status refreshItemsInternal(); } private String getVMIconPath() { String status = virtualMachine.getStatus(); if (status.equals(VM_STATUS_RUNNING)) return RUN_ICON_PATH; if (status.equals(VM_STATUS_SUSPENDED)) return STOP_ICON_PATH; return WAIT_ICON_PATH; } @Override protected void refreshItems() throws AzureCmdException { // update vm name and status icon virtualMachine = AzureSDKManagerImpl.getManager().refreshVirtualMachineInformation(virtualMachine); refreshItemsInternal(); } private void refreshItemsInternal() throws AzureCmdException { // update vm name and status icon setName(virtualMachine.getName()); setIconPath(getVMIconPath()); // load up the endpoint nodes removeAllChildNodes(); for (Endpoint endpoint : virtualMachine.getEndpoints()) { VMEndpointNode vmEndPoint = new VMEndpointNode(this, endpoint); addChildNode(vmEndPoint); vmEndPoint.refreshItems(); } } @Override protected Map<String, Class<? extends NodeActionListener>> initActions() { return ImmutableMap.of( ACTION_DELETE, DeleteVMAction.class, ACTION_DOWNLOAD_RDP_FILE, DownloadRDPAction.class, ACTION_SHUTDOWN, ShutdownVMAction.class, ACTION_START, StartVMAction.class, ACTION_RESTART, RestartVMAction.class); } @Override public List<NodeAction> getNodeActions() { // enable/disable menu items according to VM status getNodeActionByName(ACTION_SHUTDOWN).setEnabled(virtualMachine.getStatus().equals(VM_STATUS_RUNNING)); getNodeActionByName(ACTION_START).setEnabled(!virtualMachine.getStatus().equals(VM_STATUS_RUNNING)); getNodeActionByName(ACTION_RESTART).setEnabled(virtualMachine.getStatus().equals(VM_STATUS_RUNNING)); getNodeActionByName(ACTION_DOWNLOAD_RDP_FILE).setEnabled(virtualMachine.getStatus().equals(VM_STATUS_RUNNING)); return super.getNodeActions(); } public class DeleteVMAction extends NodeActionListenerAsync { int optionDialog; public DeleteVMAction() { super("Deleting VM"); } @Override protected void runInBackground(NodeActionEvent e) throws AzureCmdException { ApplicationManager.getApplication().invokeAndWait(new Runnable() { @Override public void run() { optionDialog = JOptionPane.showOptionDialog(null, "This operation will delete virtual machine " + virtualMachine.getName() + ". The associated disks will not be deleted from your storage account. " + "Are you sure you want to continue?", "Service explorer", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, new String[]{"Yes", "No"}, null); } }, ModalityState.any()); if (optionDialog == JOptionPane.YES_OPTION) { try { AzureSDKManagerImpl.getManager().deleteVirtualMachine(virtualMachine, false); ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { // instruct parent node to remove this node getParent().removeDirectChildNode(VMNode.this); } }); } catch (AzureCmdException ex) { UIHelper.showException("Error deleting virtual machine", ex); throw ex; } } } } public class DownloadRDPAction extends NodeActionListener { @Override public void actionPerformed(NodeActionEvent e) { try { JFileChooser saveFile = new JFileChooser(); saveFile.setDialogTitle("Save RDP file"); if (saveFile.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) { File rdpFile = saveFile.getSelectedFile(); if (!rdpFile.exists()) { rdpFile.createNewFile(); } FileOutputStream fileOutputStream = new FileOutputStream(rdpFile); fileOutputStream.write(AzureSDKManagerImpl.getManager().downloadRDP(virtualMachine)); fileOutputStream.flush(); fileOutputStream.close(); } } catch (Exception ex) { UIHelper.showException("Error downloading RDP file:", ex); } } } public abstract class VMNodeActionListener extends NodeActionListenerAsync { private String promptMessageFormat; private String progressMessage; private int optionDialog; public VMNodeActionListener(String promptMessageFormat, String progressMessage) { super(progressMessage); this.promptMessageFormat = promptMessageFormat; this.progressMessage = progressMessage; } @Override protected void runInBackground(NodeActionEvent e) throws AzureCmdException { ApplicationManager.getApplication().invokeAndWait(new Runnable() { @Override public void run() { optionDialog = JOptionPane.showOptionDialog(null, String.format(promptMessageFormat, virtualMachine.getName()), "Service explorer", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, new String[]{"Yes", "No"}, null); } }, ModalityState.any()); if (optionDialog == JOptionPane.YES_OPTION) { try { runVMAction(); // reload vm details refreshItems(); } catch (AzureCmdException ex) { UIHelper.showException("Error " + progressMessage + " " + virtualMachine.getName(), ex); throw ex; } } } protected void runVMAction() throws AzureCmdException {} } public class ShutdownVMAction extends VMNodeActionListener { public ShutdownVMAction() { super( "This operation will result in losing the VIP that was assigned to this virtual machine. Are you " + "sure that you want to shut down virtual machine %s?", "Shutting down VM" ); } @Override protected void runVMAction() throws AzureCmdException { AzureSDKManagerImpl.getManager().shutdownVirtualMachine(virtualMachine, true); } } public class StartVMAction extends VMNodeActionListener { public StartVMAction() { super( "Are you sure you want to start the virtual machine %s?", "Starting VM" ); } @Override protected void runVMAction() throws AzureCmdException { AzureSDKManagerImpl.getManager().startVirtualMachine(virtualMachine); } } public class RestartVMAction extends VMNodeActionListener { public RestartVMAction() { super( "Are you sure you want to restart the virtual machine %s?", "Restarting VM" ); } @Override protected void runVMAction() throws AzureCmdException { AzureSDKManagerImpl.getManager().restartVirtualMachine(virtualMachine); } } }