diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/core/FunctionUtils.java b/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/core/FunctionUtils.java index 91689b90213..4ef0b2b74f6 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/core/FunctionUtils.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/core/FunctionUtils.java @@ -57,7 +57,7 @@ import java.io.File; import java.io.IOException; import java.nio.charset.Charset; -import java.nio.file.InvalidPathException; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.*; @@ -73,21 +73,22 @@ public class FunctionUtils { "{\"id\":\"Microsoft.Azure.Functions.ExtensionBundle\",\"version\":\"[1.*, 2.0.0)\"}}\n"; private static final String DEFAULT_LOCAL_SETTINGS_JSON = "{ \"IsEncrypted\": false, \"Values\": " + "{ \"FUNCTIONS_WORKER_RUNTIME\": \"java\" } }"; + private static final String AZURE_FUNCTIONS = "azure-functions"; - public static boolean isValidStagingFolderPath(String stagingFolderPath) { - if (StringUtils.isEmpty(stagingFolderPath)) { - return false; - } - final File target = new File(stagingFolderPath); - if (target.exists()) { - return target.isDirectory(); - } else { - try { - Paths.get(stagingFolderPath); - } catch (InvalidPathException | NullPointerException ex) { - return false; + public static File getTempStagingFolder() throws IOException { + final Path path = Files.createTempDirectory(AZURE_FUNCTIONS); + final File file = path.toFile(); + FileUtils.forceDeleteOnExit(file); + return file; + } + + public static void cleanUpStagingFolder(File stagingFolder) { + try { + if (stagingFolder != null) { + FileUtils.deleteDirectory(stagingFolder); } - return true; + } catch (IOException e) { + // swallow exceptions while clean up } } diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/deploy/FunctionDeployConfiguration.java b/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/deploy/FunctionDeployConfiguration.java index ca1b0d086db..54393952c0d 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/deploy/FunctionDeployConfiguration.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/deploy/FunctionDeployConfiguration.java @@ -191,9 +191,6 @@ public void validate() throws ConfigurationException { if (StringUtils.isEmpty(this.getFunctionId())) { throw new ConfigurationException(NEED_SPECIFY_TARGET_FUNCTION); } - if (!FunctionUtils.isValidStagingFolderPath(getDeploymentStagingDirectory())) { - throw new ConfigurationException(NEED_SPECIFY_VALID_STAGING_DIRECTORY_PATH); - } } } diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/deploy/FunctionDeploymentState.java b/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/deploy/FunctionDeploymentState.java index 710fe13f5a3..bcc3f52b9e8 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/deploy/FunctionDeploymentState.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/deploy/FunctionDeploymentState.java @@ -53,6 +53,7 @@ public class FunctionDeploymentState extends AzureRunProfileState { private FunctionDeployConfiguration functionDeployConfiguration; private final FunctionDeployModel deployModel; + private File stagingFolder; /** * Place to execute the Web App deployment task. @@ -77,7 +78,8 @@ public WebAppBase executeSteps(@NotNull RunProcessHandler processHandler functionDeployConfiguration.setRuntime(runtimeConfiguration); functionDeployConfiguration.setPricingTier(appServicePlan.pricingTier().toSkuDescription().size()); // Deploy function to Azure - final File stagingFolder = new File(functionDeployConfiguration.getDeploymentStagingDirectory()); + stagingFolder = FunctionUtils.getTempStagingFolder(); + deployModel.setDeploymentStagingDirectoryPath(stagingFolder.getPath()); prepareStagingFolder(stagingFolder, processHandler); final DeployFunctionHandler deployFunctionHandler = new DeployFunctionHandler(deployModel, message -> { if (processHandler.isProcessRunning()) { @@ -87,14 +89,15 @@ public WebAppBase executeSteps(@NotNull RunProcessHandler processHandler return deployFunctionHandler.execute(); } - private void prepareStagingFolder(File stagingFolder, RunProcessHandler processHandler) { + private void prepareStagingFolder(File stagingFolder, RunProcessHandler processHandler) + throws AzureExecutionException { ReadAction.run(() -> { final Path hostJsonPath = FunctionUtils.getDefaultHostJson(project); final PsiMethod[] methods = FunctionUtils.findFunctionsByAnnotation(functionDeployConfiguration.getModule()); try { FunctionUtils.prepareStagingFolder(stagingFolder.toPath(), hostJsonPath, functionDeployConfiguration.getModule(), methods); } catch (AzureExecutionException | IOException e) { - processHandler.println(String.format("Failed to prepare staging folder, %s", e.getMessage()), ProcessOutputTypes.STDERR); + throw new AzureExecutionException("Failed to prepare staging folder"); } }); } @@ -108,12 +111,14 @@ protected Operation createOperation() { protected void onSuccess(WebAppBase result, @NotNull RunProcessHandler processHandler) { processHandler.setText("Deploy succeed"); processHandler.notifyComplete(); + FunctionUtils.cleanUpStagingFolder(stagingFolder); } @Override protected void onFail(String errMsg, @NotNull RunProcessHandler processHandler) { processHandler.println(errMsg, ProcessOutputTypes.STDERR); processHandler.notifyComplete(); + FunctionUtils.cleanUpStagingFolder(stagingFolder); } @Override diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/deploy/ui/FunctionDeploymentPanel.form b/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/deploy/ui/FunctionDeploymentPanel.form index 70ce997d603..458a21304bd 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/deploy/ui/FunctionDeploymentPanel.form +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/deploy/ui/FunctionDeploymentPanel.form @@ -1,6 +1,6 @@
- + @@ -44,7 +44,7 @@ - + @@ -52,30 +52,13 @@ - + - - - - - - - - - - - - - - - - - diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/deploy/ui/FunctionDeploymentPanel.java b/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/deploy/ui/FunctionDeploymentPanel.java index a6949d3bed2..11a30d46738 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/deploy/ui/FunctionDeploymentPanel.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/deploy/ui/FunctionDeploymentPanel.java @@ -24,10 +24,8 @@ import com.intellij.icons.AllIcons; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.Comparing; import com.intellij.packaging.artifacts.Artifact; import com.intellij.ui.HyperlinkLabel; @@ -43,7 +41,6 @@ import com.microsoft.intellij.runner.functions.core.FunctionUtils; import com.microsoft.intellij.runner.functions.deploy.FunctionDeployConfiguration; import com.microsoft.intellij.runner.functions.deploy.ui.creation.FunctionCreationDialog; -import com.microsoft.intellij.ui.util.UIUtils; import org.apache.commons.collections.MapUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.maven.project.MavenProject; @@ -72,7 +69,6 @@ public class FunctionDeploymentPanel extends AzureSettingPanel cbFunctionModule; private AppSettingsTable appSettingsTable; @@ -107,15 +103,6 @@ public void customize(JList list, Module module, int i, boolean b, boolean b1) { } }); - cbFunctionModule.addItemListener(itemEvent -> { - final String targetFolder = FunctionUtils.getTargetFolder((Module) cbFunctionModule.getSelectedItem()); - txtStagingFolder.setText(targetFolder); - }); - - txtStagingFolder.addActionListener( - UIUtils.createFileChooserListenerWithTextPath(txtStagingFolder, project, - FileChooserDescriptorFactory.createSingleFolderDescriptor())); - fillModules(); } @@ -227,7 +214,6 @@ protected void resetFromConfig(@NotNull FunctionDeployConfiguration configuratio protected void apply(@NotNull FunctionDeployConfiguration configuration) { configuration.saveTargetModule((Module) cbFunctionModule.getSelectedItem()); configuration.setAppSettings(appSettingsTable.getAppSettings()); - configuration.setDeploymentStagingDirectory(txtStagingFolder.getText()); if (selectedFunctionApp == null || selectedFunctionApp.getResource() == null) { // Use previous configuration when function is not loaded configuration.setSubscription(previousDeployConfiguration.getSubscriptionId()); diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/localrun/FunctionRunConfiguration.java b/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/localrun/FunctionRunConfiguration.java index 814c5a80ea3..321e6208975 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/localrun/FunctionRunConfiguration.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/localrun/FunctionRunConfiguration.java @@ -224,9 +224,6 @@ public void validate() throws ConfigurationException { if (!func.exists() || !func.isFile() || !func.getName().contains("func")) { throw new ConfigurationException("Please specify correct function cli path"); } - if (!FunctionUtils.isValidStagingFolderPath(getStagingFolder())) { - throw new ConfigurationException("Please specify correct staging folder path"); - } } @Override diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/localrun/FunctionRunState.java b/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/localrun/FunctionRunState.java index 011406cf9b1..f1c01d05aad 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/localrun/FunctionRunState.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/localrun/FunctionRunState.java @@ -69,6 +69,7 @@ public class FunctionRunState extends AzureRunProfileState { private static final int DEFAULT_DEBUG_PORT = 5005; private static final int MAX_PORT = 65535; + private File stagingFolder; private Process process; private Executor executor; private FunctionRunConfiguration functionRunConfiguration; @@ -106,7 +107,7 @@ private void launchDebugger(final Project project, int debugPort) { protected FunctionApp executeSteps(@NotNull RunProcessHandler processHandler, @NotNull Map telemetryMap) throws Exception { // Prepare staging Folder updateTelemetryMap(telemetryMap); - final File stagingFolder = new File(functionRunConfiguration.getStagingFolder()); + stagingFolder = FunctionUtils.getTempStagingFolder(); prepareStagingFolder(stagingFolder, processHandler); // Run Function Host runFunctionCli(processHandler, stagingFolder); @@ -167,7 +168,7 @@ private ProcessBuilder getRunFunctionCliProcessBuilder(File stagingFolder, int f return processBuilder; } - private void prepareStagingFolder(File stagingFolder, RunProcessHandler processHandler) { + private void prepareStagingFolder(File stagingFolder, RunProcessHandler processHandler) throws AzureExecutionException { ReadAction.run(() -> { final Path hostJsonPath = FunctionUtils.getDefaultHostJson(project); final Path localSettingsJson = Paths.get(functionRunConfiguration.getLocalSettingsJsonPath()); @@ -176,7 +177,7 @@ private void prepareStagingFolder(File stagingFolder, RunProcessHandler processH FunctionUtils.prepareStagingFolder(stagingFolder.toPath(), hostJsonPath, functionRunConfiguration.getModule(), methods); FunctionUtils.copyLocalSettingsToStagingFolder(stagingFolder.toPath(), localSettingsJson, functionRunConfiguration.getAppSettings()); } catch (AzureExecutionException | IOException e) { - processHandler.println(String.format("Failed to prepare staging folder, %s", e.getMessage()), ProcessOutputTypes.STDERR); + throw new AzureExecutionException("Failed to prepare staging folder", e); } }); } @@ -225,6 +226,7 @@ protected void onSuccess(FunctionApp result, RunProcessHandler processHandler) { processHandler.setText("Succeed!"); processHandler.notifyComplete(); } + FunctionUtils.cleanUpStagingFolder(stagingFolder); } @Override @@ -236,5 +238,6 @@ protected void onFail(String errMsg, RunProcessHandler processHandler) { processHandler.setText("Fail!"); processHandler.notifyComplete(); } + FunctionUtils.cleanUpStagingFolder(stagingFolder); } } diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/localrun/ui/FunctionRunPanel.form b/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/localrun/ui/FunctionRunPanel.form index 8da858aa178..d660f655247 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/localrun/ui/FunctionRunPanel.form +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/localrun/ui/FunctionRunPanel.form @@ -16,7 +16,7 @@ - + @@ -24,27 +24,9 @@ - - - - - - - - - - - - - - - - - - - + @@ -52,7 +34,7 @@ - + @@ -62,7 +44,7 @@ - + @@ -85,7 +67,7 @@ - + diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/localrun/ui/FunctionRunPanel.java b/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/localrun/ui/FunctionRunPanel.java index 761be50ebd6..917cb87cbca 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/localrun/ui/FunctionRunPanel.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/localrun/ui/FunctionRunPanel.java @@ -52,7 +52,6 @@ public class FunctionRunPanel extends AzureSettingPanel cbFunctionModule; @@ -74,15 +73,6 @@ public void customize(JList list, Module module, int i, boolean b, boolean b1) { } }); - cbFunctionModule.addItemListener(itemEvent -> { - final String targetFolder = FunctionUtils.getTargetFolder((Module) cbFunctionModule.getSelectedItem()); - txtStagingFolder.setText(targetFolder); - }); - - txtStagingFolder.addActionListener( - UIUtils.createFileChooserListenerWithTextPath(txtStagingFolder, project, - FileChooserDescriptorFactory.createSingleFolderDescriptor())); - txtFunc.addActionListener( UIUtils.createFileChooserListenerWithTextPath(txtFunc, project, FileChooserDescriptorFactory.createSingleFileDescriptor())); @@ -126,7 +116,6 @@ protected void resetFromConfig(@NotNull FunctionRunConfiguration configuration) @Override protected void apply(@NotNull FunctionRunConfiguration configuration) { configuration.setFuncPath(txtFunc.getText()); - configuration.setStagingFolder(txtStagingFolder.getText()); configuration.setAppSettings(appSettingsTable.getAppSettings()); configuration.saveModule((Module) cbFunctionModule.getSelectedItem()); }