diff --git a/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.17.aarch64 b/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.17.aarch64 new file mode 100644 index 000000000..09ad14ef9 --- /dev/null +++ b/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.17.aarch64 @@ -0,0 +1,25 @@ +FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal AS graalvm +ENV LANG=en_US.UTF-8 +RUN dnf update -y && dnf install -y gcc glibc-devel zlib-devel libstdc++-static tar && dnf clean all && rm -rf /var/cache/dnf +RUN curl -4 -L https://download.oracle.com/graalvm/17/archive/graalvm-jdk-17.0.12_linux-aarch64_bin.tar.gz -o /tmp/graalvm.tar.gz \ + && mkdir -p /usr/lib/graalvm \ + && tar -zxf /tmp/graalvm.tar.gz -C /usr/lib/graalvm --strip-components 1 \ + && rm -rf /tmp/* +ENV PATH="/usr/lib/graalvm/bin:${PATH}" +WORKDIR /home/app +COPY classes /home/app/classes +COPY dependency/* /home/app/libs/ +COPY graalvm-reachability-metadat[a] /home/app/graalvm-reachability-metadata +COPY nativ[e]/generated /home/app/ +COPY *.args /home/app/graalvm-native-image.args +RUN native-image @/home/app/graalvm-native-image.args -H:Class=io.micronaut.function.aws.runtime.MicronautLambdaRuntime -H:Name=application -cp "/home/app/libs/*:/home/app/classes/" + +FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal +WORKDIR /function +RUN dnf update -y && dnf install -y zip && dnf clean all +COPY --from=graalvm /home/app/application /function/func +RUN echo "#!/bin/sh" >> bootstrap && echo "set -euo pipefail" >> bootstrap && echo "./func -XX:MaximumHeapSizePercent=80 -Dio.netty.allocator.numDirectArenas=0 -Dio.netty.noPreferDirect=true -Djava.library.path=$(pwd)" >> bootstrap +RUN chmod 777 bootstrap +RUN chmod 777 func +RUN zip -j function.zip bootstrap func +ENTRYPOINT ["/function/func"] diff --git a/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.17.amd64 b/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.17.amd64 new file mode 100644 index 000000000..f10bbfa97 --- /dev/null +++ b/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.17.amd64 @@ -0,0 +1,25 @@ +FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal AS graalvm +ENV LANG=en_US.UTF-8 +RUN dnf update -y && dnf install -y gcc glibc-devel zlib-devel libstdc++-static tar && dnf clean all && rm -rf /var/cache/dnf +RUN curl -4 -L https://download.oracle.com/graalvm/17/archive/graalvm-jdk-17.0.12_linux-x64_bin.tar.gz -o /tmp/graalvm.tar.gz \ + && mkdir -p /usr/lib/graalvm \ + && tar -zxf /tmp/graalvm.tar.gz -C /usr/lib/graalvm --strip-components 1 \ + && rm -rf /tmp/* +ENV PATH="/usr/lib/graalvm/bin:${PATH}" +WORKDIR /home/app +COPY classes /home/app/classes +COPY dependency/* /home/app/libs/ +COPY graalvm-reachability-metadat[a] /home/app/graalvm-reachability-metadata +COPY nativ[e]/generated /home/app/ +COPY *.args /home/app/graalvm-native-image.args +RUN native-image @/home/app/graalvm-native-image.args -H:Class=io.micronaut.function.aws.runtime.MicronautLambdaRuntime -H:Name=application -cp "/home/app/libs/*:/home/app/classes/" + +FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal +WORKDIR /function +RUN dnf update -y && dnf install -y zip && dnf clean all +COPY --from=graalvm /home/app/application /function/func +RUN echo "#!/bin/sh" >> bootstrap && echo "set -euo pipefail" >> bootstrap && echo "./func -XX:MaximumHeapSizePercent=80 -Dio.netty.allocator.numDirectArenas=0 -Dio.netty.noPreferDirect=true -Djava.library.path=$(pwd)" >> bootstrap +RUN chmod 777 bootstrap +RUN chmod 777 func +RUN zip -j function.zip bootstrap func +ENTRYPOINT ["/function/func"] diff --git a/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.amd64 b/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.21.aarch64 similarity index 70% rename from micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.amd64 rename to micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.21.aarch64 index 1d4e36335..75093c3a3 100644 --- a/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.amd64 +++ b/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.21.aarch64 @@ -1,7 +1,7 @@ -FROM amazonlinux:2023 AS graalvm +FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal AS graalvm ENV LANG=en_US.UTF-8 -RUN yum update -y && yum install -y gcc gcc-c++ glibc-devel curl-minimal bash zlib zlib-devel zlib-static zip tar gzip && yum clean all && rm -rf /var/cache/yum -RUN curl -4 -L https://download.oracle.com/graalvm/17/latest/graalvm-jdk-17_linux-x64_bin.tar.gz -o /tmp/graalvm.tar.gz \ +RUN dnf update -y && dnf install -y gcc glibc-devel zlib-devel libstdc++-static tar && dnf clean all && rm -rf /var/cache/dnf +RUN curl -4 -L https://download.oracle.com/graalvm/21/latest/graalvm-jdk-21_linux-aarch64_bin.tar.gz -o /tmp/graalvm.tar.gz \ && mkdir -p /usr/lib/graalvm \ && tar -zxf /tmp/graalvm.tar.gz -C /usr/lib/graalvm --strip-components 1 \ && rm -rf /tmp/* @@ -14,9 +14,9 @@ COPY nativ[e]/generated /home/app/ COPY *.args /home/app/graalvm-native-image.args RUN native-image @/home/app/graalvm-native-image.args -H:Class=io.micronaut.function.aws.runtime.MicronautLambdaRuntime -H:Name=application -cp "/home/app/libs/*:/home/app/classes/" -FROM amazonlinux:2023 +FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal WORKDIR /function -RUN yum update -y && yum install -y zip && yum clean all +RUN dnf update -y && dnf install -y zip && dnf clean all COPY --from=graalvm /home/app/application /function/func RUN echo "#!/bin/sh" >> bootstrap && echo "set -euo pipefail" >> bootstrap && echo "./func -XX:MaximumHeapSizePercent=80 -Dio.netty.allocator.numDirectArenas=0 -Dio.netty.noPreferDirect=true -Djava.library.path=$(pwd)" >> bootstrap RUN chmod 777 bootstrap diff --git a/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.aarch64 b/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.21.amd64 similarity index 70% rename from micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.aarch64 rename to micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.21.amd64 index 1f8383faa..13b985fdd 100644 --- a/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.aarch64 +++ b/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.21.amd64 @@ -1,7 +1,7 @@ -FROM amazonlinux:2023 AS graalvm +FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal AS graalvm ENV LANG=en_US.UTF-8 -RUN yum update -y && yum install -y gcc gcc-c++ glibc-devel curl-minimal bash zlib zlib-devel zlib-static zip tar gzip && yum clean all && rm -rf /var/cache/yum -RUN curl -4 -L https://download.oracle.com/graalvm/17/latest/graalvm-jdk-17_linux-aarch64_bin.tar.gz -o /tmp/graalvm.tar.gz \ +RUN dnf update -y && dnf install -y gcc glibc-devel zlib-devel libstdc++-static tar && dnf clean all && rm -rf /var/cache/dnf +RUN curl -4 -L https://download.oracle.com/graalvm/21/latest/graalvm-jdk-21_linux-x64_bin.tar.gz -o /tmp/graalvm.tar.gz \ && mkdir -p /usr/lib/graalvm \ && tar -zxf /tmp/graalvm.tar.gz -C /usr/lib/graalvm --strip-components 1 \ && rm -rf /tmp/* @@ -14,9 +14,9 @@ COPY nativ[e]/generated /home/app/ COPY *.args /home/app/graalvm-native-image.args RUN native-image @/home/app/graalvm-native-image.args -H:Class=io.micronaut.function.aws.runtime.MicronautLambdaRuntime -H:Name=application -cp "/home/app/libs/*:/home/app/classes/" -FROM amazonlinux:2023 +FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal WORKDIR /function -RUN yum update -y && yum install -y zip && yum clean all +RUN dnf update -y && dnf install -y zip && dnf clean all COPY --from=graalvm /home/app/application /function/func RUN echo "#!/bin/sh" >> bootstrap && echo "set -euo pipefail" >> bootstrap && echo "./func -XX:MaximumHeapSizePercent=80 -Dio.netty.allocator.numDirectArenas=0 -Dio.netty.noPreferDirect=true -Djava.library.path=$(pwd)" >> bootstrap RUN chmod 777 bootstrap diff --git a/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/verify.groovy b/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/verify.groovy index 8ef82edda..5e3c3024e 100644 --- a/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/verify.groovy +++ b/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/verify.groovy @@ -1,9 +1,3 @@ -File dockerfile = new File("$basedir/target", "Dockerfile") -File expectedDockerfile = new File(basedir, "Dockerfile.${graalVmArch()}") -String expectedDockerfileText = expectedDockerfile.text.replace("17", "${System.getProperty("java.specification.version")}") - -assert dockerfile.text == expectedDockerfileText - static String graalVmArch() { String osArch = System.getProperty("os.arch") if ("aarch64".equals(osArch)) { @@ -13,6 +7,11 @@ static String graalVmArch() { } } +File dockerfile = new File("$basedir/target", "Dockerfile") +File expectedDockerfile = new File(basedir, "Dockerfile.${System.getProperty("java.specification.version")}.${graalVmArch()}") + +assert dockerfile.text == expectedDockerfile.text + File log = new File(basedir, 'build.log') assert log.exists() assert log.text.contains("Copying /function/function.zip") \ No newline at end of file diff --git a/micronaut-maven-plugin/pom.xml b/micronaut-maven-plugin/pom.xml index 6859b7c7d..aa73ad0c4 100644 --- a/micronaut-maven-plugin/pom.xml +++ b/micronaut-maven-plugin/pom.xml @@ -123,6 +123,12 @@ 5.12.0 test + + org.junit-pioneer + junit-pioneer + 2.3.0 + test + diff --git a/micronaut-maven-plugin/src/main/java/io/micronaut/maven/AbstractDockerMojo.java b/micronaut-maven-plugin/src/main/java/io/micronaut/maven/AbstractDockerMojo.java index c79b83b78..784d73080 100644 --- a/micronaut-maven-plugin/src/main/java/io/micronaut/maven/AbstractDockerMojo.java +++ b/micronaut-maven-plugin/src/main/java/io/micronaut/maven/AbstractDockerMojo.java @@ -61,6 +61,10 @@ public abstract class AbstractDockerMojo extends AbstractMicronautMojo { public static final String X86_64_ARCH = "x64"; public static final String DEFAULT_ORACLE_LINUX_VERSION = "ol9"; public static final String ORACLE_CLOUD_FUNCTION_DEFAULT_CMD = "CMD [\"io.micronaut.oraclecloud.function.http.HttpFunction::handleRequest\"]"; + public static final String GRAALVM_DOWNLOAD_URL = "https://download.oracle.com/graalvm/%s/%s/graalvm-jdk-%s_linux-%s_bin.tar.gz"; + + //Latest version of GraalVM for JDK 17 available under the GraalVM Free Terms and Conditions (GFTC) licence + public static final String GRAALVM_FOR_JDK17 = "17.0.12"; protected final MavenProject mavenProject; protected final JibConfigurationService jibConfigurationService; @@ -145,18 +149,21 @@ protected ArtifactVersion javaVersion() { } /** - * @return the GraalVM version from the graalvm.version property, which is expected to come from the - * Micronaut Parent POM. + * @return the JVM version to use for GraalVM. */ - protected String graalVmVersion() { - return mavenProject.getProperties().getProperty("graal.version"); + protected String graalVmJvmVersion() { + return javaVersion().getMajorVersion() == 17 ? "17" : "21"; } /** - * @return the JVM version to use for GraalVM. + * @return the GraalVM download URL depending on the Java version. */ - protected String graalVmJvmVersion() { - return javaVersion().getMajorVersion() == 17 ? "17" : "21"; + protected String graalVmDownloadUrl() { + if (javaVersion().getMajorVersion() == 17) { + return GRAALVM_DOWNLOAD_URL.formatted(17, "archive", GRAALVM_FOR_JDK17, graalVmArch()); + } else { + return GRAALVM_DOWNLOAD_URL.formatted(21, "latest", 21, graalVmArch()); + } } /** diff --git a/micronaut-maven-plugin/src/main/java/io/micronaut/maven/DockerNativeMojo.java b/micronaut-maven-plugin/src/main/java/io/micronaut/maven/DockerNativeMojo.java index 640127885..08a793e92 100644 --- a/micronaut-maven-plugin/src/main/java/io/micronaut/maven/DockerNativeMojo.java +++ b/micronaut-maven-plugin/src/main/java/io/micronaut/maven/DockerNativeMojo.java @@ -148,19 +148,13 @@ private void checkJavaVersion(int maxAllowedVersion) throws MojoExecutionExcepti private void buildDockerNativeLambda() throws IOException { var buildImageCmdArguments = new HashMap(); - getLog().info("Using GRAALVM_JVM_VERSION: " + graalVmJvmVersion()); - getLog().info("Using GRAALVM_ARCH: " + graalVmArch()); - // Starter sets the right class in pom.xml: // - For applications: io.micronaut.function.aws.runtime.MicronautLambdaRuntime // - For function apps: com.example.BookLambdaRuntime - getLog().info("Using CLASS_NAME: " + mainClass); BuildImageCmd buildImageCmd = addNativeImageBuildArgs(buildImageCmdArguments, () -> { try { return dockerService.buildImageCmd(DockerfileMojo.DOCKERFILE_AWS_CUSTOM_RUNTIME) - .withBuildArg("GRAALVM_VERSION", graalVmVersion()) - .withBuildArg("GRAALVM_JVM_VERSION", graalVmJvmVersion()) - .withBuildArg("GRAALVM_ARCH", graalVmArch()); + .withBuildArg("GRAALVM_DOWNLOAD_URL", graalVmDownloadUrl()); } catch (IOException e) { throw new DockerClientException(e.getMessage(), e); } @@ -204,7 +198,6 @@ private void buildDockerfile(String dockerfileName, boolean passClassName) throw var buildImageCmdArguments = new HashMap(); - getLog().info("Using BASE_IMAGE: " + from); if (StringUtils.isNotEmpty(baseImageRun) && Boolean.FALSE.equals(staticNativeImage)) { buildImageCmdArguments.put("BASE_IMAGE_RUN", baseImageRun); } @@ -235,10 +228,7 @@ private BuildImageCmd addNativeImageBuildArgs(Map buildImageCmdA BuildImageCmd buildImageCmd = buildImageCmdSupplier.get(); for (Map.Entry buildArg : buildImageCmdArguments.entrySet()) { - String key = buildArg.getKey(); - String value = buildArg.getValue(); - getLog().info("Using " + key + ": " + value); - buildImageCmd.withBuildArg(key, value); + buildImageCmd.withBuildArg(buildArg.getKey(), buildArg.getValue()); } getNetworkMode().ifPresent(buildImageCmd::withNetworkMode); diff --git a/micronaut-maven-plugin/src/main/java/io/micronaut/maven/DockerfileMojo.java b/micronaut-maven-plugin/src/main/java/io/micronaut/maven/DockerfileMojo.java index b3cffc60a..6649a47db 100644 --- a/micronaut-maven-plugin/src/main/java/io/micronaut/maven/DockerfileMojo.java +++ b/micronaut-maven-plugin/src/main/java/io/micronaut/maven/DockerfileMojo.java @@ -19,7 +19,6 @@ import io.micronaut.maven.jib.JibConfigurationService; import io.micronaut.maven.jib.JibMicronautExtension; import io.micronaut.maven.services.ApplicationConfigurationService; -import io.micronaut.maven.services.CompilerService; import io.micronaut.maven.services.DockerService; import io.micronaut.maven.services.ExecutorService; import org.apache.maven.execution.MavenSession; @@ -74,15 +73,13 @@ public class DockerfileMojo extends AbstractDockerMojo { public static final String NATIVE_BUILD_TOOLS_MAVEN_PLUGIN = "org.graalvm.buildtools:native-maven-plugin"; private final ExecutorService executorService; - private final CompilerService compilerService; @Inject public DockerfileMojo(MavenProject mavenProject, DockerService dockerService, JibConfigurationService jibConfigurationService, ApplicationConfigurationService applicationConfigurationService, ExecutorService executorService, - MavenSession mavenSession, MojoExecution mojoExecution, CompilerService compilerService) { + MavenSession mavenSession, MojoExecution mojoExecution) { super(mavenProject, jibConfigurationService, applicationConfigurationService, dockerService, mavenSession, mojoExecution); this.executorService = executorService; - this.compilerService = compilerService; } @Override @@ -190,7 +187,6 @@ private void processDockerfile(File dockerfile) throws IOException { if (dockerfile != null) { var allLines = Files.readAllLines(dockerfile.toPath()); var result = new ArrayList(); - for (String line : allLines) { if (!line.startsWith("ARG")) { if (line.contains("BASE_IMAGE_RUN")) { @@ -199,12 +195,10 @@ private void processDockerfile(File dockerfile) throws IOException { result.add(line.replace("${BASE_IMAGE}", getFrom())); } else if (line.contains("BASE_JAVA_IMAGE")) { result.add(line.replace("${BASE_JAVA_IMAGE}", getBaseImage())); - } else if (line.contains("GRAALVM_") || line.contains("CLASS_NAME")) { - result.add(line - .replace("${GRAALVM_JVM_VERSION}", graalVmJvmVersion()) - .replace("${GRAALVM_ARCH}", graalVmArch()) - .replace("${CLASS_NAME}", mainClass) - ); + } else if (line.contains("GRAALVM_DOWNLOAD_URL")) { + result.add(line.replace("${GRAALVM_DOWNLOAD_URL}", graalVmDownloadUrl())); + } else if (line.contains("CLASS_NAME")) { + result.add(line.replace("${CLASS_NAME}", mainClass)); } else if (line.contains("PORT")) { result.add(line.replace("${PORT}", getPort())); } else { diff --git a/micronaut-maven-plugin/src/main/java/io/micronaut/maven/services/DockerService.java b/micronaut-maven-plugin/src/main/java/io/micronaut/maven/services/DockerService.java index 02bbea5dc..b08427a21 100644 --- a/micronaut-maven-plugin/src/main/java/io/micronaut/maven/services/DockerService.java +++ b/micronaut-maven-plugin/src/main/java/io/micronaut/maven/services/DockerService.java @@ -131,6 +131,9 @@ public BuildImageCmd buildImageCmd() { */ public String buildImage(BuildImageCmd builder) { verifyDockerRunning(); + if (builder.getBuildArgs() != null) { + builder.getBuildArgs().forEach((k, v) -> LOG.info("Using {}: {}", k, v)); + } BuildImageResultCallback resultCallback = new BuildImageResultCallback() { @Override public void onNext(BuildResponseItem item) { diff --git a/micronaut-maven-plugin/src/main/resources/dockerfiles/DockerfileNativeLambda b/micronaut-maven-plugin/src/main/resources/dockerfiles/DockerfileNativeLambda index 37e219906..e5746f970 100644 --- a/micronaut-maven-plugin/src/main/resources/dockerfiles/DockerfileNativeLambda +++ b/micronaut-maven-plugin/src/main/resources/dockerfiles/DockerfileNativeLambda @@ -1,9 +1,8 @@ -FROM amazonlinux:2023 AS graalvm +FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal AS graalvm ENV LANG=en_US.UTF-8 -ARG GRAALVM_JVM_VERSION -ARG GRAALVM_ARCH -RUN yum update -y && yum install -y gcc gcc-c++ glibc-devel curl-minimal bash zlib zlib-devel zlib-static zip tar gzip && yum clean all && rm -rf /var/cache/yum -RUN curl -4 -L https://download.oracle.com/graalvm/${GRAALVM_JVM_VERSION}/latest/graalvm-jdk-${GRAALVM_JVM_VERSION}_linux-${GRAALVM_ARCH}_bin.tar.gz -o /tmp/graalvm.tar.gz \ +RUN dnf update -y && dnf install -y gcc glibc-devel zlib-devel libstdc++-static tar && dnf clean all && rm -rf /var/cache/dnf +ARG GRAALVM_DOWNLOAD_URL +RUN curl -4 -L ${GRAALVM_DOWNLOAD_URL} -o /tmp/graalvm.tar.gz \ && mkdir -p /usr/lib/graalvm \ && tar -zxf /tmp/graalvm.tar.gz -C /usr/lib/graalvm --strip-components 1 \ && rm -rf /tmp/* @@ -17,9 +16,9 @@ COPY *.args /home/app/graalvm-native-image.args ARG CLASS_NAME RUN native-image @/home/app/graalvm-native-image.args -H:Class=${CLASS_NAME} -H:Name=application -cp "/home/app/libs/*:/home/app/classes/" -FROM amazonlinux:2023 +FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal WORKDIR /function -RUN yum update -y && yum install -y zip && yum clean all +RUN dnf update -y && dnf install -y zip && dnf clean all COPY --from=graalvm /home/app/application /function/func RUN echo "#!/bin/sh" >> bootstrap && echo "set -euo pipefail" >> bootstrap && echo "./func -XX:MaximumHeapSizePercent=80 -Dio.netty.allocator.numDirectArenas=0 -Dio.netty.noPreferDirect=true -Djava.library.path=$(pwd)" >> bootstrap RUN chmod 777 bootstrap diff --git a/micronaut-maven-plugin/src/test/java/io/micronaut/maven/DockerNativeMojoTest.java b/micronaut-maven-plugin/src/test/java/io/micronaut/maven/DockerNativeMojoTest.java new file mode 100644 index 000000000..20b332697 --- /dev/null +++ b/micronaut-maven-plugin/src/test/java/io/micronaut/maven/DockerNativeMojoTest.java @@ -0,0 +1,60 @@ +package io.micronaut.maven; + +import org.apache.maven.execution.MavenSession; +import org.apache.maven.plugin.MojoExecution; +import org.apache.maven.project.MavenProject; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junitpioneer.jupiter.RestoreSystemProperties; +import org.junitpioneer.jupiter.SetSystemProperty; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.Properties; + +import static io.micronaut.maven.AbstractDockerMojo.X86_64_ARCH; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@RestoreSystemProperties +class DockerNativeMojoTest { + + @ParameterizedTest + @CsvSource({ + "17,https://download.oracle.com/graalvm/17/archive/graalvm-jdk-17.0.12_linux-x64_bin.tar.gz", + "21,https://download.oracle.com/graalvm/21/latest/graalvm-jdk-21_linux-x64_bin.tar.gz" + }) + @SetSystemProperty(key = "os.arch", value = X86_64_ARCH) + void testGraalVmDownloadUrl(String javaVersion, String expectedUrl) throws URISyntaxException, IOException, InterruptedException { + var project = mock(MavenProject.class); + var session = mock(MavenSession.class); + var execution = mock(MojoExecution.class); + var properties = new Properties(1); + properties.put("maven.compiler.target", javaVersion); + + when(session.getCurrentProject()).thenReturn(project); + when(session.getUserProperties()).thenReturn(new Properties()); + when(session.getSystemProperties()).thenReturn(new Properties()); + when(project.getProperties()).thenReturn(properties); + + var mojo = new DockerNativeMojo(project, null, null, null, session, execution); + + var actualUrl = mojo.graalVmDownloadUrl(); + + assertEquals(expectedUrl, actualUrl); + + var client = HttpClient.newHttpClient(); + var request = HttpRequest.newBuilder() + .uri(new URI(actualUrl)) + .method("HEAD", HttpRequest.BodyPublishers.noBody()) + .build(); + var response = client.send(request, HttpResponse.BodyHandlers.discarding()); + + assertEquals(200, response.statusCode()); + } +}