diff --git a/eng/versioning/version_client.txt b/eng/versioning/version_client.txt index d21b021f3f34..6bcb9d87bf40 100644 --- a/eng/versioning/version_client.txt +++ b/eng/versioning/version_client.txt @@ -257,7 +257,7 @@ com.azure.spring:spring-cloud-azure-stream-binder-servicebus;4.16.0;4.17.0-beta. com.azure.spring:spring-cloud-azure-trace-sleuth;4.16.0;4.17.0-beta.1 com.azure.resourcemanager:azure-resourcemanager;2.36.0;2.37.0-beta.1 com.azure.resourcemanager:azure-resourcemanager-appplatform;2.36.0;2.37.0-beta.1 -com.azure.resourcemanager:azure-resourcemanager-appservice;2.36.0;2.37.0-beta.1 +com.azure.resourcemanager:azure-resourcemanager-appservice;2.36.1;2.37.0-beta.1 com.azure.resourcemanager:azure-resourcemanager-authorization;2.36.0;2.37.0-beta.1 com.azure.resourcemanager:azure-resourcemanager-cdn;2.36.0;2.37.0-beta.1 com.azure.resourcemanager:azure-resourcemanager-compute;2.36.0;2.37.0-beta.1 diff --git a/sdk/resourcemanager/azure-resourcemanager-appservice/CHANGELOG.md b/sdk/resourcemanager/azure-resourcemanager-appservice/CHANGELOG.md index c54d637a95f4..655c65125f99 100644 --- a/sdk/resourcemanager/azure-resourcemanager-appservice/CHANGELOG.md +++ b/sdk/resourcemanager/azure-resourcemanager-appservice/CHANGELOG.md @@ -10,6 +10,13 @@ ### Other Changes +## 2.36.1 (2024-03-04) + +### Bugs Fixed + +- Fixed NullPointerException when updating Function App in Azure Container Apps. +- Fixed a bug that `withPrivateRegistryImage` doesn't work as expected for Function App in Azure Container Apps. + ## 2.36.0 (2024-02-29) ### Other Changes diff --git a/sdk/resourcemanager/azure-resourcemanager-appservice/assets.json b/sdk/resourcemanager/azure-resourcemanager-appservice/assets.json index ae1487d0da68..6c164a5492b8 100644 --- a/sdk/resourcemanager/azure-resourcemanager-appservice/assets.json +++ b/sdk/resourcemanager/azure-resourcemanager-appservice/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "java", "TagPrefix": "java/resourcemanager/azure-resourcemanager-appservice", - "Tag": "java/resourcemanager/azure-resourcemanager-appservice_b33aba24fe" + "Tag": "java/resourcemanager/azure-resourcemanager-appservice_c5279701f3" } diff --git a/sdk/resourcemanager/azure-resourcemanager-appservice/src/main/java/com/azure/resourcemanager/appservice/implementation/FunctionAppImpl.java b/sdk/resourcemanager/azure-resourcemanager-appservice/src/main/java/com/azure/resourcemanager/appservice/implementation/FunctionAppImpl.java index 63a3efd5e980..38ca4916b624 100644 --- a/sdk/resourcemanager/azure-resourcemanager-appservice/src/main/java/com/azure/resourcemanager/appservice/implementation/FunctionAppImpl.java +++ b/sdk/resourcemanager/azure-resourcemanager-appservice/src/main/java/com/azure/resourcemanager/appservice/implementation/FunctionAppImpl.java @@ -59,6 +59,7 @@ import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; +import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -415,7 +416,17 @@ public FunctionAppImpl withPrivateDockerHubImage(String imageAndTag) { @Override public FunctionAppImpl withPrivateRegistryImage(String imageAndTag, String serverUrl) { ensureLinuxPlan(); - return super.withPrivateRegistryImage(imageAndTag, serverUrl); + super.withPrivateRegistryImage(imageAndTag, serverUrl); + if (isFunctionAppOnACA()) { + try { + URL url = new URL(serverUrl); + // remove URL protocol, as ACA don't allow that + withAppSetting(SETTING_REGISTRY_SERVER, url.getAuthority() + url.getFile()); + } catch (MalformedURLException e) { + // NO-OP, server url is not in URL format + } + } + return this; } @Override @@ -646,7 +657,7 @@ private void adaptForFunctionAppOnACA() { siteConfigInner.withLinuxFxVersion(this.siteConfig.linuxFxVersion()); siteConfigInner.withMinimumElasticInstanceCount(this.siteConfig.minimumElasticInstanceCount()); siteConfigInner.withFunctionAppScaleLimit(this.siteConfig.functionAppScaleLimit()); - siteConfigInner.withAppSettings(this.siteConfig.appSettings()); + siteConfigInner.withAppSettings(this.siteConfig.appSettings() == null ? new ArrayList<>() : this.siteConfig.appSettings()); if (!appSettingsToAdd.isEmpty() || !appSettingsToRemove.isEmpty()) { for (String settingToRemove : appSettingsToRemove) { siteConfigInner.appSettings().removeIf(kvPair -> Objects.equals(settingToRemove, kvPair.name())); diff --git a/sdk/resourcemanager/azure-resourcemanager-appservice/src/test/java/com/azure/resourcemanager/appservice/FunctionAppsTests.java b/sdk/resourcemanager/azure-resourcemanager-appservice/src/test/java/com/azure/resourcemanager/appservice/FunctionAppsTests.java index 757395ab6b6c..6e8c21a96659 100644 --- a/sdk/resourcemanager/azure-resourcemanager-appservice/src/test/java/com/azure/resourcemanager/appservice/FunctionAppsTests.java +++ b/sdk/resourcemanager/azure-resourcemanager-appservice/src/test/java/com/azure/resourcemanager/appservice/FunctionAppsTests.java @@ -529,6 +529,10 @@ public void canCreateAndUpdateFunctionAppOnACA() { Assertions.assertEquals("mySettingValue", functionApp.getAppSettings().get("customSetting").value()); // Assertions.assertEquals("connectionValue", functionApp.getConnectionStrings().get("connectionName").value()); + functionApp.update() + .withPublicDockerHubImage("mcr.microsoft.com/azure-functions/dotnet7-quickstart-demo:1.0") + .apply(); + functionApp.update() .withMaxReplicas(15) .apply(); @@ -560,6 +564,8 @@ public void canCreateAndUpdateFunctionAppOnAcaWithPrivateRegistryImage() { Assertions.assertThrows(ManagementException.class, () -> appServiceManager .serviceClient().getWebApps().getByResourceGroup(rgName1, webappName1)); + String password = "PASSWORD"; + String managedEnvironmentId = createAcaEnvironment(region, resourceGroup); appServiceManager .functionApps() @@ -569,8 +575,8 @@ public void canCreateAndUpdateFunctionAppOnAcaWithPrivateRegistryImage() { .withManagedEnvironmentId(managedEnvironmentId) .withMaxReplicas(10) .withMinReplicas(3) - .withPrivateRegistryImage("xiaofeiacr.azurecr.io/samples/nginx:latest", "xiaofeiacr.azurecr.io") - .withCredentials("xiaofeiacr", "PASSWORD") + .withPrivateRegistryImage("samples/nginx:latest", "https://xiaofeiacr.azurecr.io") + .withCredentials("xiaofeiacr", password) .withRuntimeVersion("4") .create(); @@ -584,6 +590,8 @@ public void canCreateAndUpdateFunctionAppOnAcaWithPrivateRegistryImage() { functionApp.update() .withMaxReplicas(15) + .withPrivateRegistryImage("xiaofeiacr.azurecr.io/samples/nginx:latest", "https://xiaofeiacr.azurecr.io") + .withCredentials("xiaofeiacr", password) .withNewStorageAccount(generateRandomResourceName("as", 15), StorageAccountSkuType.STANDARD_LRS) .apply(); @@ -592,6 +600,13 @@ public void canCreateAndUpdateFunctionAppOnAcaWithPrivateRegistryImage() { Assertions.assertEquals(3, functionApp.minReplicas()); Assertions.assertNotEquals(connectionString, functionApp.getAppSettings().get(KEY_AZURE_WEB_JOBS_STORAGE).value()); + + // when serverUrl has no protocol(https), use imageAndTag directly + functionApp.update() + .withMaxReplicas(15) + .withPrivateRegistryImage("xiaofeiacr.azurecr.io/samples/nginx:latest", "xiaofeiacr.azurecr.io") + .withCredentials("xiaofeiacr", password) + .apply(); } private String createAcaEnvironment(Region region, ResourceGroup resourceGroup) {