diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/actions/functions/DeployFunctionAction.java b/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/actions/functions/DeployFunctionAction.java index 7278a31385..f0882129c8 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/actions/functions/DeployFunctionAction.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/actions/functions/DeployFunctionAction.java @@ -74,6 +74,10 @@ public void update(AnActionEvent event) { } private void runConfiguration(Module module) { + // todo: investigate when will module be null + if (module == null) { + return; + } final Project project = module.getProject(); final RunManagerEx manager = RunManagerEx.getInstanceEx(project); final ConfigurationFactory factory = new FunctionDeploymentConfigurationFactory(configType); diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/actions/functions/RunFunctionAction.java b/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/actions/functions/RunFunctionAction.java index 728fd00cf1..31e03f5258 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/actions/functions/RunFunctionAction.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/actions/functions/RunFunctionAction.java @@ -64,6 +64,10 @@ public void update(AnActionEvent event) { } private void runConfiguration(Module module) { + // todo: investigate when will module be null + if (module == null) { + return; + } final Project project = module.getProject(); final RunManagerEx manager = RunManagerEx.getInstanceEx(project); final ConfigurationFactory factory = new FunctionRunConfigurationFactory(configType); 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 fad7f764af..34c3dbaa58 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 @@ -198,7 +198,7 @@ public static Map prepareStagingFolder(Path stagi final List jarFiles = new ArrayList<>(); OrderEnumerator.orderEntries(module).productionOnly().forEachLibrary(lib -> { - if (ArrayUtils.contains(lib.getName().split("\\:"), FUNCTION_JAVA_LIBRARY_ARTIFACT_ID)) { + if (StringUtils.isNotEmpty(lib.getName()) && ArrayUtils.contains(lib.getName().split("\\:"), FUNCTION_JAVA_LIBRARY_ARTIFACT_ID)) { return true; } @@ -337,6 +337,9 @@ private static Binding getBinding(final Project project, JvmAnnotation annotatio private static Binding getUserDefinedBinding(final Project project, PsiAnnotation annotation) throws AzureExecutionException { PsiJavaCodeReferenceElement referenceElement = annotation.getNameReferenceElement(); + if (referenceElement == null) { + return null; + } PsiAnnotation customBindingAnnotation = AnnotationUtil.findAnnotation((PsiModifierListOwner) referenceElement.resolve(), AZURE_FUNCTION_CUSTOM_BINDING_CLASS); @@ -427,7 +430,7 @@ private static void copyFilesWithDefaultContent(Path sourcePath, File dest, Stri if (src != null && src.exists()) { FileUtils.copyFile(src, dest); } else { - FileUtils.write(src, defaultContent, Charset.defaultCharset()); + FileUtils.write(dest, defaultContent, Charset.defaultCharset()); } } 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 bcc3f52b9e..ced9b8a698 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 @@ -51,6 +51,9 @@ public class FunctionDeploymentState extends AzureRunProfileState { + private static final String TARGET_FUNCTION_DOES_NOT_EXIST = + "Target function does not exist, please select a valid function in function deployment run configuration."; + private FunctionDeployConfiguration functionDeployConfiguration; private final FunctionDeployModel deployModel; private File stagingFolder; @@ -72,6 +75,9 @@ public WebAppBase executeSteps(@NotNull RunProcessHandler processHandler // Update run time information by function app final FunctionApp functionApp = AzureFunctionMvpModel.getInstance() .getFunctionById(functionDeployConfiguration.getSubscriptionId(), functionDeployConfiguration.getFunctionId()); + if (functionApp == null) { + throw new AzureExecutionException(TARGET_FUNCTION_DOES_NOT_EXIST); + } final AppServicePlan appServicePlan = AppServiceUtils.getAppServicePlanByAppService(functionApp); final IntelliJFunctionRuntimeConfiguration runtimeConfiguration = new IntelliJFunctionRuntimeConfiguration(); runtimeConfiguration.setOs(appServicePlan.operatingSystem() == OperatingSystem.WINDOWS ? "windows" : "linux"); diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/library/function/DeployFunctionHandler.java b/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/library/function/DeployFunctionHandler.java index 94036ac614..77d6d7133c 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/library/function/DeployFunctionHandler.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/runner/functions/library/function/DeployFunctionHandler.java @@ -43,7 +43,7 @@ import com.microsoft.azure.functions.annotation.AuthorizationLevel; import com.microsoft.azure.management.appservice.FunctionApp; import com.microsoft.azure.management.appservice.FunctionApp.Update; -import com.microsoft.intellij.runner.functions.library.IAppServiceContext; +import com.microsoft.intellij.runner.functions.deploy.FunctionDeployModel; import com.microsoft.intellij.runner.functions.library.IPrompter; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -93,23 +93,22 @@ public class DeployFunctionHandler { + "function information (Attempt %d/%d)..."; private static final OperatingSystemEnum DEFAULT_OS = OperatingSystemEnum.Windows; - private IAppServiceContext ctx; + private FunctionDeployModel model; private IPrompter prompter; - public DeployFunctionHandler(IAppServiceContext ctx, IPrompter prompter) { - Preconditions.checkNotNull(ctx); - this.ctx = ctx; + public DeployFunctionHandler(FunctionDeployModel model, IPrompter prompter) { + Preconditions.checkNotNull(model); + this.model = model; this.prompter = prompter; } public FunctionApp execute() throws Exception { - final FunctionApp app = getFunctionApp(); updateFunctionAppSettings(app); final DeployTarget deployTarget = new DeployTarget(app, DeployTargetType.FUNCTION); prompt(DEPLOY_START); getArtifactHandler().publish(deployTarget); - prompt(String.format(DEPLOY_FINISH, ctx.getAppName())); + prompt(String.format(DEPLOY_FINISH, model.getAppName())); listHTTPTriggerUrls(); return (FunctionApp) deployTarget.getApp(); } @@ -120,7 +119,7 @@ private void updateFunctionAppSettings(final FunctionApp app) throws AzureExecut final Update update = app.update(); configureAppSettings(update::withAppSettings, getAppSettingsWithDefaultValue()); update.apply(); - prompt(String.format(FUNCTION_APP_UPDATE_DONE, ctx.getAppName())); + prompt(String.format(FUNCTION_APP_UPDATE_DONE, model.getAppName())); } private void configureAppSettings(final Consumer withAppSettings, final Map appSettings) { @@ -178,12 +177,12 @@ private List listFunctions() throws AzureExecutionException, I prompt(String.format(SYNCING_TRIGGERS_AND_FETCH_FUNCTION_INFORMATION, i + 1, LIST_TRIGGERS_MAX_RETRY)); functionApp.syncTriggers(); final List triggers = - ctx.getAzureClient().appServices().functionApps() - .listFunctions(ctx.getResourceGroup(), - ctx.getAppName()).stream() - .map(envelope -> FunctionResource.parseFunction(envelope)) - .filter(function -> function != null) - .collect(Collectors.toList()); + model.getAzureClient().appServices().functionApps() + .listFunctions(model.getResourceGroup(), + model.getAppName()).stream() + .map(envelope -> FunctionResource.parseFunction(envelope)) + .filter(function -> function != null) + .collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(triggers)) { return triggers; } @@ -192,7 +191,7 @@ private List listFunctions() throws AzureExecutionException, I } private OperatingSystemEnum getOsEnum() throws AzureExecutionException { - final RuntimeConfiguration runtime = ctx.getRuntime(); + final RuntimeConfiguration runtime = model.getRuntime(); if (runtime != null && StringUtils.isNotBlank(runtime.getOs())) { return Utils.parseOperationSystem(runtime.getOs()); } @@ -200,7 +199,7 @@ private OperatingSystemEnum getOsEnum() throws AzureExecutionException { } private DeploymentType getDeploymentType() throws AzureExecutionException { - final DeploymentType deploymentType = DeploymentType.fromString(ctx.getDeploymentType()); + final DeploymentType deploymentType = DeploymentType.fromString(model.getDeploymentType()); return deploymentType == DeploymentType.EMPTY ? getDeploymentTypeByRuntime() : deploymentType; } @@ -217,22 +216,20 @@ private DeploymentType getDeploymentTypeByRuntime() throws AzureExecutionExcepti } private boolean isDedicatedPricingTier() { - return AppServiceUtils.getPricingTierFromString(ctx.getPricingTier()) != null; + return AppServiceUtils.getPricingTierFromString(model.getPricingTier()) != null; } - private FunctionApp getFunctionApp() { + private FunctionApp getFunctionApp() throws AzureExecutionException { try { - return ctx.getAzureClient().appServices().functionApps().getByResourceGroup(ctx.getResourceGroup(), - ctx.getAppName()); - } catch (Exception ex) { - // Swallow exception for non-existing Azure Functions + return model.getAzureClient().appServices().functionApps().getById(model.getFunctionId()); + } catch (IOException e) { + throw new AzureExecutionException("Failed to get azure client"); } - return null; } // region get App Settings private Map getAppSettingsWithDefaultValue() { - final Map settings = ctx.getAppSettings(); + final Map settings = model.getAppSettings(); overrideDefaultAppSetting(settings, FUNCTIONS_WORKER_RUNTIME_NAME, SET_FUNCTIONS_WORKER_RUNTIME, FUNCTIONS_WORKER_RUNTIME_VALUE, CHANGE_FUNCTIONS_WORKER_RUNTIME); setDefaultAppSetting(settings, FUNCTIONS_EXTENSION_VERSION_NAME, SET_FUNCTIONS_EXTENSION_VERSION, @@ -268,7 +265,7 @@ private ArtifactHandler getArtifactHandler() throws AzureExecutionException { final DeploymentType deploymentType = getDeploymentType(); switch (deploymentType) { case MSDEPLOY: - builder = new MSDeployArtifactHandlerImpl.Builder().functionAppName(this.ctx.getAppName()); + builder = new MSDeployArtifactHandlerImpl.Builder().functionAppName(this.model.getAppName()); break; case FTP: builder = new FTPArtifactHandlerImpl.Builder(); @@ -290,7 +287,7 @@ private ArtifactHandler getArtifactHandler() throws AzureExecutionException { throw new AzureExecutionException(UNKNOW_DEPLOYMENT_TYPE); } return builder - .stagingDirectoryPath(this.ctx.getDeploymentStagingDirectoryPath()) + .stagingDirectoryPath(this.model.getDeploymentStagingDirectoryPath()) .build(); } diff --git a/Utils/azuretools-core/src/com/microsoft/azuretools/sdkmanage/AzureCliAzureManager.java b/Utils/azuretools-core/src/com/microsoft/azuretools/sdkmanage/AzureCliAzureManager.java index 5afd7b9f83..6bff7bb813 100644 --- a/Utils/azuretools-core/src/com/microsoft/azuretools/sdkmanage/AzureCliAzureManager.java +++ b/Utils/azuretools-core/src/com/microsoft/azuretools/sdkmanage/AzureCliAzureManager.java @@ -182,7 +182,7 @@ private static class LazyLoader { * identity/implementation/IdentityClient.java#L366 */ private Pair getAccessTokenViaCli(String tid, @Nullable String resource) throws IOException { - if (!PATTERN_TENANT.matcher(tid).matches()) { + if (StringUtils.isEmpty(tid) || !PATTERN_TENANT.matcher(tid).matches()) { throw new InvalidParameterException(String.format("[%s] is not a valid tenant ID", tid)); } else if (StringUtils.isNotEmpty(resource) && !PATTERN_RESOURCE.matcher(resource).matches()) { throw new InvalidParameterException(String.format("[%s] is not a valid resource endpoint", resource));