Skip to content

Commit 24767a1

Browse files
XiaofeiCaoCopilot
andauthored
mgmt appservice, more supported stacks in RuntimeStack (Azure#44388)
* list latest runtime stacks * new stacks * add disabled * changelog, removed ones not on Portal * suppress unchecked * Update sdk/resourcemanager/azure-resourcemanager-test/src/main/java/com/azure/resourcemanager/test/utils/CliRunner.java Co-authored-by: Copilot <[email protected]> * javadoc * final class * spotless --------- Co-authored-by: Copilot <[email protected]>
1 parent 24e7b30 commit 24767a1

File tree

5 files changed

+220
-78
lines changed

5 files changed

+220
-78
lines changed

sdk/resourcemanager/azure-resourcemanager-appservice/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44

55
### Features Added
66

7+
- Supported Java SE 21 in `RuntimeStack` for `WebApp`.
8+
- Supported Tomcat 10.1, JBoss EAP 8 and Java 21 in `RuntimeStack` for `WebApp`.
9+
- Supported .Net 6, 8, 9 in `RuntimeStack` for `WebApp`.
10+
- Supported PHP 8.2, 8.3 in `RuntimeStack` for `WebApp`.
11+
- Supported Python 3.9, 3.10, 3.11, 3.12 in `RuntimeStack` for `WebApp`.
12+
713
### Breaking Changes
814

915
### Bugs Fixed

sdk/resourcemanager/azure-resourcemanager-appservice/src/main/java/com/azure/resourcemanager/appservice/models/RuntimeStack.java

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ public class RuntimeStack {
1717
/** .NET Core v3.1. */
1818
public static final RuntimeStack NETCORE_V3_1 = COLLECTION.addValue(new RuntimeStack("DOTNETCORE", "3.1"));
1919

20+
/** .NET Core v8.0. */
21+
public static final RuntimeStack NETCORE_V8_0 = COLLECTION.addValue(new RuntimeStack("DOTNETCORE", "8.0"));
22+
23+
/** .NET Core v9.0. */
24+
public static final RuntimeStack NETCORE_V9_0 = COLLECTION.addValue(new RuntimeStack("DOTNETCORE", "9.0"));
25+
2026
/** JAVA JRE 8. */
2127
public static final RuntimeStack JAVA_8_JRE8 = COLLECTION.addValue(new RuntimeStack("JAVA", "8-jre8"));
2228

@@ -26,6 +32,9 @@ public class RuntimeStack {
2632
/** JAVA JAVA 17. */
2733
public static final RuntimeStack JAVA_17_JAVA17 = COLLECTION.addValue(new RuntimeStack("JAVA", "17-java17"));
2834

35+
/** JAVA JAVA 21. */
36+
public static final RuntimeStack JAVA_21_JAVA21 = COLLECTION.addValue(new RuntimeStack("JAVA", "21-java21"));
37+
2938
/** Node.JS 10.1. */
3039
public static final RuntimeStack NODEJS_10_1 = COLLECTION.addValue(new RuntimeStack("NODE", "10.1"));
3140

@@ -44,6 +53,15 @@ public class RuntimeStack {
4453
/** Node.JS 14 LTS. */
4554
public static final RuntimeStack NODEJS_14_LTS = COLLECTION.addValue(new RuntimeStack("NODE", "14-lts"));
4655

56+
/** Node.JS 18 LTS. */
57+
public static final RuntimeStack NODEJS_18_LTS = COLLECTION.addValue(new RuntimeStack("NODE", "18-lts"));
58+
59+
/** Node.JS 20 LTS. */
60+
public static final RuntimeStack NODEJS_20_LTS = COLLECTION.addValue(new RuntimeStack("NODE", "20-lts"));
61+
62+
/** Node.JS 22 LTS. */
63+
public static final RuntimeStack NODEJS_22_LTS = COLLECTION.addValue(new RuntimeStack("NODE", "22-lts"));
64+
4765
/** PHP 7.2. */
4866
public static final RuntimeStack PHP_7_2 = COLLECTION.addValue(new RuntimeStack("PHP", "7.2"));
4967

@@ -53,6 +71,12 @@ public class RuntimeStack {
5371
/** PHP 7.4. */
5472
public static final RuntimeStack PHP_7_4 = COLLECTION.addValue(new RuntimeStack("PHP", "7.4"));
5573

74+
/** PHP 8.2. */
75+
public static final RuntimeStack PHP_8_2 = COLLECTION.addValue(new RuntimeStack("PHP", "8.2"));
76+
77+
/** PHP 8.3. */
78+
public static final RuntimeStack PHP_8_3 = COLLECTION.addValue(new RuntimeStack("PHP", "8.3"));
79+
5680
/** PYTHON 3.6. */
5781
public static final RuntimeStack PYTHON_3_6 = COLLECTION.addValue(new RuntimeStack("PYTHON", "3.6"));
5882

@@ -62,6 +86,18 @@ public class RuntimeStack {
6286
/** PYTHON 3.8. */
6387
public static final RuntimeStack PYTHON_3_8 = COLLECTION.addValue(new RuntimeStack("PYTHON", "3.8"));
6488

89+
/** PYTHON 3.9. */
90+
public static final RuntimeStack PYTHON_3_9 = COLLECTION.addValue(new RuntimeStack("PYTHON", "3.9"));
91+
92+
/** PYTHON 3.10. */
93+
public static final RuntimeStack PYTHON_3_10 = COLLECTION.addValue(new RuntimeStack("PYTHON", "3.10"));
94+
95+
/** PYTHON 3.11. */
96+
public static final RuntimeStack PYTHON_3_11 = COLLECTION.addValue(new RuntimeStack("PYTHON", "3.11"));
97+
98+
/** PYTHON 3.12. */
99+
public static final RuntimeStack PYTHON_3_12 = COLLECTION.addValue(new RuntimeStack("PYTHON", "3.12"));
100+
65101
/** RUBY 2.5. */
66102
public static final RuntimeStack RUBY_2_5 = COLLECTION.addValue(new RuntimeStack("RUBY", "2.5"));
67103

@@ -74,12 +110,30 @@ public class RuntimeStack {
74110
/** Tomcat 8.5-jre8 image with catalina root set to Azure wwwroot. */
75111
public static final RuntimeStack TOMCAT_8_5_JRE8 = COLLECTION.addValue(new RuntimeStack("TOMCAT", "8.5-jre8"));
76112

113+
/** Tomcat 9.0-java21 image with catalina root set to Azure wwwroot. */
114+
public static final RuntimeStack TOMCAT_9_0_JAVA21 = COLLECTION.addValue(new RuntimeStack("TOMCAT", "9.0-java21"));
115+
116+
/** Tomcat 9.0-java17 image with catalina root set to Azure wwwroot. */
117+
public static final RuntimeStack TOMCAT_9_0_JAVA17 = COLLECTION.addValue(new RuntimeStack("TOMCAT", "9.0-java17"));
118+
77119
/** Tomcat 9.0-java11 image with catalina root set to Azure wwwroot. */
78120
public static final RuntimeStack TOMCAT_9_0_JAVA11 = COLLECTION.addValue(new RuntimeStack("TOMCAT", "9.0-java11"));
79121

80122
/** Tomcat 9.0-jre8 image with catalina root set to Azure wwwroot. */
81123
public static final RuntimeStack TOMCAT_9_0_JRE8 = COLLECTION.addValue(new RuntimeStack("TOMCAT", "9.0-jre8"));
82124

125+
/** Tomcat 10.1-java21 image with catalina root set to Azure wwwroot. */
126+
public static final RuntimeStack TOMCAT_10_1_JAVA21
127+
= COLLECTION.addValue(new RuntimeStack("TOMCAT", "10.1-java21"));
128+
129+
/** Tomcat 10.1-java17 image with catalina root set to Azure wwwroot. */
130+
public static final RuntimeStack TOMCAT_10_1_JAVA17
131+
= COLLECTION.addValue(new RuntimeStack("TOMCAT", "10.1-java17"));
132+
133+
/** Tomcat 10.1-java11 image with catalina root set to Azure wwwroot. */
134+
public static final RuntimeStack TOMCAT_10_1_JAVA11
135+
= COLLECTION.addValue(new RuntimeStack("TOMCAT", "10.1-java11"));
136+
83137
/** Tomcat 10.0-java17 image with catalina root set to Azure wwwroot. */
84138
public static final RuntimeStack TOMCAT_10_0_JAVA17
85139
= COLLECTION.addValue(new RuntimeStack("TOMCAT", "10.0-java17"));
@@ -100,6 +154,12 @@ public class RuntimeStack {
100154
/** Tomcat 10.0-jre8 image with catalina root set to Azure wwwroot. */
101155
public static final RuntimeStack TOMCAT_10_0_JRE8 = COLLECTION.addValue(new RuntimeStack("TOMCAT", "10.0-jre8"));
102156

157+
/** JBOSS EAP 8-java17. */
158+
public static final RuntimeStack JBOSS_EAP_8_JAVA17 = COLLECTION.addValue(new RuntimeStack("JBOSSEAP", "8-java17"));
159+
160+
/** JBOSS EAP 8-java11. */
161+
public static final RuntimeStack JBOSS_EAP_8_JAVA11 = COLLECTION.addValue(new RuntimeStack("JBOSSEAP", "8-java11"));
162+
103163
/** JBOSS EAP 7.2-java8. */
104164
public static final RuntimeStack JBOSS_EAP_7_2_JAVA8
105165
= COLLECTION.addValue(new RuntimeStack("JBOSSEAP", "7.2-java8"));
@@ -110,6 +170,9 @@ public class RuntimeStack {
110170
/** JBOSS EAP 7-java11. */
111171
public static final RuntimeStack JBOSS_EAP_7_JAVA11 = COLLECTION.addValue(new RuntimeStack("JBOSSEAP", "7-java11"));
112172

173+
/** JBOSS EAP 7-java17. */
174+
public static final RuntimeStack JBOSS_EAP_7_JAVA17 = COLLECTION.addValue(new RuntimeStack("JBOSSEAP", "7-java17"));
175+
113176
/** The name of the language runtime stack. */
114177
private final String stack;
115178
/** The version of the runtime. */

sdk/resourcemanager/azure-resourcemanager-appservice/src/test/java/com/azure/resourcemanager/appservice/RuntimeStackTests.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,19 @@
33

44
package com.azure.resourcemanager.appservice;
55

6+
import com.azure.core.util.BinaryData;
67
import com.azure.resourcemanager.appservice.models.RuntimeStack;
8+
import com.azure.resourcemanager.test.utils.CliRunner;
79
import org.junit.jupiter.api.Assertions;
10+
import org.junit.jupiter.api.Disabled;
811
import org.junit.jupiter.api.Test;
912

13+
import java.io.IOException;
14+
import java.util.Arrays;
1015
import java.util.Collection;
16+
import java.util.List;
17+
import java.util.Set;
18+
import java.util.stream.Collectors;
1119

1220
public class RuntimeStackTests {
1321

@@ -17,4 +25,46 @@ public void verifyDeprecatedNotInGetAll() {
1725
Assertions.assertTrue(stacks.contains(RuntimeStack.TOMCAT_10_0_JAVA11));
1826
Assertions.assertFalse(stacks.contains(RuntimeStack.TOMCAT_10_0_JRE11));
1927
}
28+
29+
/**
30+
* This test is for syncing RuntimeStack with latest supported stacks from backend.
31+
* To run this test, upgrade Azure CLI to latest version by running "az upgrade", and remove "@Disabled".
32+
*/
33+
@Test
34+
@Disabled
35+
public void listNewRuntimeStacks() throws IOException, InterruptedException {
36+
Set<String> latestStacks = getLatestStacks();
37+
Set<String> allCurrentStacks = Arrays.stream(RuntimeStack.class.getDeclaredFields())
38+
.filter(field -> field.getType() == RuntimeStack.class)
39+
.map(field -> {
40+
try {
41+
return field.get(null).toString();
42+
} catch (IllegalAccessException e) {
43+
throw new RuntimeException(e);
44+
}
45+
})
46+
.collect(Collectors.toSet());
47+
Set<String> supportedStacks
48+
= RuntimeStack.getAll().stream().map(RuntimeStack::toString).collect(Collectors.toSet());
49+
List<String> newStacks = latestStacks.stream()
50+
.filter(stack -> !allCurrentStacks.contains(stack))
51+
.distinct()
52+
.sorted()
53+
.collect(Collectors.toList());
54+
List<String> newDeprecated = supportedStacks.stream()
55+
.filter(stack -> !latestStacks.contains(stack))
56+
.distinct()
57+
.sorted()
58+
.collect(Collectors.toList());
59+
System.out.println("New stacks: " + newStacks);
60+
System.out.println("New deprecated stacks: " + newDeprecated);
61+
}
62+
63+
@SuppressWarnings("unchecked")
64+
private Set<String> getLatestStacks() throws IOException, InterruptedException {
65+
String cliOutput = CliRunner.run("az webapp list-runtimes --os linux");
66+
List<String> outputList
67+
= BinaryData.fromString(cliOutput.substring(cliOutput.indexOf("["))).toObject(List.class);
68+
return outputList.stream().map(stack -> String.join(" ", stack.split(":"))).collect(Collectors.toSet());
69+
}
2070
}

sdk/resourcemanager/azure-resourcemanager-test/src/main/java/com/azure/resourcemanager/test/ResourceManagerTestProxyTestBase.java

Lines changed: 2 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
package com.azure.resourcemanager.test;
44

55
import com.azure.core.credential.TokenCredential;
6-
import com.azure.core.exception.ClientAuthenticationException;
76
import com.azure.core.http.HttpClient;
87
import com.azure.core.http.HttpPipeline;
98
import com.azure.core.http.ProxyOptions;
@@ -22,26 +21,23 @@
2221
import com.azure.core.test.utils.MockTokenCredential;
2322
import com.azure.core.test.utils.ResourceNamer;
2423
import com.azure.core.util.Configuration;
25-
import com.azure.core.util.CoreUtils;
2624
import com.azure.core.util.logging.ClientLogger;
2725
import com.azure.identity.DefaultAzureCredentialBuilder;
28-
import com.azure.identity.implementation.util.IdentityUtil;
2926
import com.azure.json.JsonProviders;
3027
import com.azure.json.JsonReader;
3128
import com.azure.resourcemanager.test.model.AzureUser;
3229
import com.azure.resourcemanager.test.policy.HttpDebugLoggingPolicy;
30+
import com.azure.resourcemanager.test.utils.CliRunner;
3331
import org.junit.jupiter.api.Assertions;
3432
import org.junit.jupiter.api.extension.ExtensionContext;
3533
import org.junit.jupiter.api.extension.InvocationInterceptor;
3634
import org.junit.jupiter.api.extension.ReflectiveInvocationContext;
3735
import org.junit.jupiter.api.extension.RegisterExtension;
3836
import reactor.core.Exceptions;
3937

40-
import java.io.BufferedReader;
4138
import java.io.ByteArrayOutputStream;
4239
import java.io.DataOutputStream;
4340
import java.io.IOException;
44-
import java.io.InputStreamReader;
4541
import java.io.OutputStream;
4642
import java.io.PrintStream;
4743
import java.io.UnsupportedEncodingException;
@@ -69,7 +65,6 @@
6965
import java.util.List;
7066
import java.util.Map;
7167
import java.util.Objects;
72-
import java.util.concurrent.TimeUnit;
7368
import java.util.function.Supplier;
7469
import java.util.regex.Pattern;
7570
import java.util.stream.Collectors;
@@ -238,70 +233,8 @@ protected AzureUser azureCliSignedInUser() {
238233
if (!isPlaybackMode()) {
239234
String azCommand = "az ad signed-in-user show --output json";
240235

241-
final Pattern windowsProcessErrorMessage = Pattern.compile("'azd?' is not recognized");
242-
final Pattern shProcessErrorMessage = Pattern.compile("azd?:.*not found");
243236
try {
244-
String starter;
245-
String switcher;
246-
if (IdentityUtil.isWindowsPlatform()) {
247-
starter = "cmd.exe";
248-
switcher = "/c";
249-
} else {
250-
starter = "/bin/sh";
251-
switcher = "-c";
252-
}
253-
254-
ProcessBuilder builder = new ProcessBuilder(starter, switcher, azCommand.toString());
255-
// Redirects stdin to dev null, helps to avoid messages sent in by the cmd process to upgrade etc.
256-
builder.redirectInput(ProcessBuilder.Redirect.from(IdentityUtil.NULL_FILE));
257-
258-
builder.redirectErrorStream(true);
259-
Process process = builder.start();
260-
261-
StringBuilder output = new StringBuilder();
262-
try (BufferedReader reader
263-
= new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) {
264-
String line;
265-
while (true) {
266-
line = reader.readLine();
267-
if (line == null) {
268-
break;
269-
}
270-
271-
if (windowsProcessErrorMessage.matcher(line).find()
272-
|| shProcessErrorMessage.matcher(line).find()) {
273-
throw LOGGER.logExceptionAsError(new RuntimeException(
274-
"AzureCliCredential authentication unavailable. Azure CLI not installed."
275-
+ "To mitigate this issue, please refer to the troubleshooting guidelines here at "
276-
+ "https://aka.ms/azsdk/java/identity/azclicredential/troubleshoot"));
277-
}
278-
output.append(line);
279-
}
280-
}
281-
String processOutput = output.toString();
282-
283-
// wait(at most) 10 seconds for the process to complete
284-
process.waitFor(10, TimeUnit.SECONDS);
285-
286-
if (process.exitValue() != 0) {
287-
if (processOutput.length() > 0) {
288-
if (processOutput.contains("az login") || processOutput.contains("az account set")) {
289-
throw LOGGER.logExceptionAsError(new RuntimeException(
290-
"AzureCliCredential authentication unavailable. Azure CLI not installed."
291-
+ "To mitigate this issue, please refer to the troubleshooting guidelines here at "
292-
+ "https://aka.ms/azsdk/java/identity/azclicredential/troubleshoot"));
293-
}
294-
throw LOGGER.logExceptionAsError(
295-
new ClientAuthenticationException("get Azure CLI current signed-in user failed", null));
296-
} else {
297-
throw LOGGER.logExceptionAsError(
298-
new ClientAuthenticationException("Failed to invoke Azure CLI ", null));
299-
}
300-
}
301-
302-
LOGGER
303-
.verbose("Get Azure CLI signed-in user => A response was received from Azure CLI, deserializing the"
304-
+ " response into an signed-in user.");
237+
String processOutput = CliRunner.run(azCommand);
305238
try (JsonReader reader = JsonProviders.createReader(processOutput)) {
306239
Map<String, Object> signedInUserInfo = reader.readMap(JsonReader::readUntyped);
307240
String userPrincipalName = (String) signedInUserInfo.get("userPrincipalName");
@@ -315,15 +248,6 @@ protected AzureUser azureCliSignedInUser() {
315248
return azureCliUser;
316249
}
317250

318-
private static String getSafeWorkingDirectory() {
319-
if (IdentityUtil.isWindowsPlatform()) {
320-
String windowsSystemRoot = System.getenv("SystemRoot");
321-
return CoreUtils.isNullOrEmpty(windowsSystemRoot) ? null : windowsSystemRoot + "\\system32";
322-
} else {
323-
return "/bin/";
324-
}
325-
}
326-
327251
/**
328252
* Gets the test profile.
329253
* @return The test profile.

0 commit comments

Comments
 (0)