diff --git a/src/functions/newsletter-subscription/build.gradle b/src/functions/newsletter-subscription/build.gradle index 2567ed13..920efce7 100644 --- a/src/functions/newsletter-subscription/build.gradle +++ b/src/functions/newsletter-subscription/build.gradle @@ -1,76 +1,90 @@ -plugins { - id("com.github.johnrengelman.shadow") version "7.1.2" - id("io.micronaut.application") version "3.6.2" -} - -group = "microanut.mushop.newsletter.subscription" - -repositories { - mavenCentral() -} - -dependencies { - implementation("io.micronaut:micronaut-validation") - implementation("io.micronaut:micronaut-jackson-databind") - implementation("io.micronaut:micronaut-runtime") - implementation("jakarta.annotation:jakarta.annotation-api") - implementation("io.micronaut:micronaut-http-client") - implementation 'javax.mail:mail:1.5.0-b01' - - runtimeOnly("org.slf4j:slf4j-simple") - implementation("io.micronaut:micronaut-validation") - - testImplementation("com.fnproject.fn:testing-junit4") - testImplementation("io.micronaut:micronaut-http-client") - -} - -application { - mainClass.set("com.example.Application") -} - -java { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 -} - -tasks { - // the base image for Oracle Function is fnproject/fn-java-fdk:jre11-latest - // TODO: build fnproject image on top of graalvm-ce -// if (javaBaseImage == "graalvm") { -// dockerfile { -// baseImage = "ghcr.io/graalvm/graalvm-ce:ol8-java11-22" -// } -// } - - dockerfileNative { - args("-XX:MaximumHeapSizePercent=80") - instruction "RUN echo 'http://dl-cdn.alpinelinux.org/alpine/v3.11/main' >> /etc/apk/repositories && apk update && apk add 'zlib<1.2.12'" - } - - dockerBuild { - images = ["phx.ocir.io/oraclelabs/micronaut-showcase/mushop/$project.name-${javaBaseImage}:$project.version"] - } - - dockerBuildNative { - images = ["phx.ocir.io/oraclelabs/micronaut-showcase/mushop/${project.name}-native:$project.version"] - } -} - -graalvmNative.toolchainDetection = false -graalvmNative { - binaries.configureEach { - buildArgs.add("--initialize-at-build-time=newsletter.subscription") - buildArgs.add("--static") - buildArgs.add("--add-exports=org.graalvm.nativeimage.builder/com.oracle.svm.core.jni=ALL-UNNAMED") - } -} - -micronaut { - runtime("oracle_function") - testRuntime("junit5") - processing { - incremental(true) - annotations("newsletter.subscription.*") - } -} +plugins { + id("com.github.johnrengelman.shadow") version "8.1.1" + id("io.micronaut.application") version "4.3.4" + id("io.micronaut.aot") version "4.3.4" +} + +group = "microanut.mushop.newsletter.subscription" + +repositories { + mavenCentral() +} + +dependencies { + annotationProcessor("io.micronaut.validation:micronaut-validation-processor") + annotationProcessor("io.micronaut:micronaut-http-validation") + annotationProcessor("io.micronaut.serde:micronaut-serde-processor") + annotationProcessor("io.micronaut.openapi:micronaut-openapi") + + implementation("io.micronaut.validation:micronaut-validation") + implementation("io.micronaut.serde:micronaut-serde-jackson") + implementation("io.micronaut:micronaut-runtime") + implementation("jakarta.annotation:jakarta.annotation-api") + implementation("io.micronaut:micronaut-http-client") + implementation("io.micronaut.email:micronaut-email-javamail") + + compileOnly("io.micronaut.openapi:micronaut-openapi-annotations") + + runtimeOnly("org.slf4j:slf4j-simple") + runtimeOnly("org.yaml:snakeyaml") + + testImplementation("com.fnproject.fn:testing-junit4") + testImplementation("io.micronaut:micronaut-http-client") + +} + +application { + mainClass.set("com.example.Application") +} + +java { + sourceCompatibility = JavaVersion.toVersion("21") + targetCompatibility = JavaVersion.toVersion("21") +} + +tasks { + if (javaBaseImage == "graalvm") { + dockerfile { + baseImage = "ghcr.io/graalvm/native-image-community:21" + } + } + + dockerfileNative { + args("-XX:MaximumHeapSizePercent=80") + instruction "RUN echo 'http://dl-cdn.alpinelinux.org/alpine/v3.11/main' >> /etc/apk/repositories && apk update && apk add 'zlib<1.2.12'" + } + + dockerBuild { + images = ["phx.ocir.io/oraclelabs/micronaut-showcase/mushop/$project.name-${javaBaseImage}:$project.version"] + } + + dockerBuildNative { + images = ["phx.ocir.io/oraclelabs/micronaut-showcase/mushop/${project.name}-native:$project.version"] + } +} + +graalvmNative.toolchainDetection = false +graalvmNative { + binaries.configureEach { + buildArgs.add("--initialize-at-build-time=newsletter.subscription") + buildArgs.add("--static") + buildArgs.add("--add-exports=org.graalvm.nativeimage.builder/com.oracle.svm.core.jni=ALL-UNNAMED") + } +} + +micronaut { + runtime("oracle_function") + testRuntime("junit5") + processing { + incremental(true) + annotations("newsletter.subscription.*") + }aot { + optimizeServiceLoading = false + convertYamlToJava = false + precomputeOperations = true + cacheEnvironment = true + optimizeClassLoading = true + deduceEnvironment = true + optimizeNetty = true + } +} diff --git a/src/functions/newsletter-subscription/gradle.properties b/src/functions/newsletter-subscription/gradle.properties index 301958be..010ee876 100644 --- a/src/functions/newsletter-subscription/gradle.properties +++ b/src/functions/newsletter-subscription/gradle.properties @@ -1,3 +1,3 @@ -micronautVersion=3.7.3 -version=2.0.99-SNAPSHOT -javaBaseImage=graalvm +micronautVersion=4.3.4 +version=2.0.99-SNAPSHOT +javaBaseImage=graalvm diff --git a/src/functions/newsletter-subscription/gradle/wrapper/gradle-wrapper.jar b/src/functions/newsletter-subscription/gradle/wrapper/gradle-wrapper.jar index 249e5832..d64cd491 100644 Binary files a/src/functions/newsletter-subscription/gradle/wrapper/gradle-wrapper.jar and b/src/functions/newsletter-subscription/gradle/wrapper/gradle-wrapper.jar differ diff --git a/src/functions/newsletter-subscription/gradle/wrapper/gradle-wrapper.properties b/src/functions/newsletter-subscription/gradle/wrapper/gradle-wrapper.properties index ae04661e..a80b22ce 100644 --- a/src/functions/newsletter-subscription/gradle/wrapper/gradle-wrapper.properties +++ b/src/functions/newsletter-subscription/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/functions/newsletter-subscription/gradlew b/src/functions/newsletter-subscription/gradlew index a69d9cb6..1aa94a42 100755 --- a/src/functions/newsletter-subscription/gradlew +++ b/src/functions/newsletter-subscription/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,13 +80,11 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,22 +131,29 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/src/functions/newsletter-subscription/gradlew.bat b/src/functions/newsletter-subscription/gradlew.bat index f127cfd4..7101f8e4 100755 --- a/src/functions/newsletter-subscription/gradlew.bat +++ b/src/functions/newsletter-subscription/gradlew.bat @@ -1,91 +1,92 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/functions/newsletter-subscription/src/main/java/newsletter/subscription/JavaMailSender.java b/src/functions/newsletter-subscription/src/main/java/newsletter/subscription/JavaMailSender.java index 965449f7..1e222ef1 100644 --- a/src/functions/newsletter-subscription/src/main/java/newsletter/subscription/JavaMailSender.java +++ b/src/functions/newsletter-subscription/src/main/java/newsletter/subscription/JavaMailSender.java @@ -1,84 +1,84 @@ -package newsletter.subscription; - -import io.micronaut.context.annotation.Property; -import jakarta.inject.Singleton; - -import javax.mail.Authenticator; -import javax.mail.Message; -import javax.mail.MessagingException; -import javax.mail.Multipart; -import javax.mail.PasswordAuthentication; -import javax.mail.Session; -import javax.mail.Transport; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; -import java.util.Properties; - -@Singleton -public class JavaMailSender implements MailSender { - - private final MailConfiguration configuration; - private final String senderEmail; - - public JavaMailSender( - @Property(name = "approved.sender.email") String senderEmail, - MailConfiguration configuration) { - this.configuration = configuration; - this.senderEmail = senderEmail; - } - - @Override - public String send(String to, String subject, String body) { - try { - final Session mailSession = createSession(); - MimeMessage message = new MimeMessage(mailSession); - message.setFrom(new InternetAddress(senderEmail)); - message.setRecipients( - Message.RecipientType.TO, InternetAddress.parse(to)); - message.setSubject("Hello from Mushop"); - String msg = "Thanks for confirming your subscription!"; - - MimeBodyPart mimeBodyPart = new MimeBodyPart(); - mimeBodyPart.setContent(msg, "text/html"); - - Multipart multipart = new MimeMultipart(); - multipart.addBodyPart(mimeBodyPart); - - message.setContent(multipart); - message.saveChanges(); - final String messageID = message.getMessageID(); - - final Transport transport = mailSession.getTransport(); - try { - transport.connect(configuration.getHost(), configuration.getUser(), configuration.getPassword()); - transport.sendMessage(message, message.getAllRecipients()); - return messageID; - } finally { - transport.close(); - } - } catch (MessagingException e) { - throw new RuntimeException("Error sending message: " + e.getMessage(), e); - } - } - - private Session createSession() { - Properties prop = new Properties(); - prop.put("mail.transport.protocol", "smtp"); - prop.put("mail.smtp.auth", true); - prop.put("mail.smtp.starttls.enable", "true"); - prop.put("mail.smtp.ssl.protocols", "TLSv1.2"); - prop.put("mail.smtp.starttls.required", "true"); - prop.put("mail.smtp.auth.login.disable", "true"); - prop.put("mail.smtp.host", configuration.getHost()); - prop.put("mail.smtp.port", String.valueOf(configuration.getPort())); - prop.put("mail.smtp.ssl.trust", configuration.getHost()); - return Session.getInstance(prop, new Authenticator() { - @Override - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(configuration.getUser(), configuration.getPassword()); - } - }); - } -} +package newsletter.subscription; + +import io.micronaut.context.annotation.Property; +import jakarta.inject.Singleton; + +import jakarta.mail.Authenticator; +import jakarta.mail.Message; +import jakarta.mail.MessagingException; +import jakarta.mail.Multipart; +import jakarta.mail.PasswordAuthentication; +import jakarta.mail.Session; +import jakarta.mail.Transport; +import jakarta.mail.internet.InternetAddress; +import jakarta.mail.internet.MimeBodyPart; +import jakarta.mail.internet.MimeMessage; +import jakarta.mail.internet.MimeMultipart; +import java.util.Properties; + +@Singleton +public class JavaMailSender implements MailSender { + + private final MailConfiguration configuration; + private final String senderEmail; + + public JavaMailSender( + @Property(name = "approved.sender.email") String senderEmail, + MailConfiguration configuration) { + this.configuration = configuration; + this.senderEmail = senderEmail; + } + + @Override + public String send(String to, String subject, String body) { + try { + final Session mailSession = createSession(); + MimeMessage message = new MimeMessage(mailSession); + message.setFrom(new InternetAddress(senderEmail)); + message.setRecipients( + Message.RecipientType.TO, InternetAddress.parse(to)); + message.setSubject("Hello from Mushop"); + String msg = "Thanks for confirming your subscription!"; + + MimeBodyPart mimeBodyPart = new MimeBodyPart(); + mimeBodyPart.setContent(msg, "text/html"); + + Multipart multipart = new MimeMultipart(); + multipart.addBodyPart(mimeBodyPart); + + message.setContent(multipart); + message.saveChanges(); + final String messageID = message.getMessageID(); + + final Transport transport = mailSession.getTransport(); + try { + transport.connect(configuration.getHost(), configuration.getUser(), configuration.getPassword()); + transport.sendMessage(message, message.getAllRecipients()); + return messageID; + } finally { + transport.close(); + } + } catch (MessagingException e) { + throw new RuntimeException("Error sending message: " + e.getMessage(), e); + } + } + + private Session createSession() { + Properties prop = new Properties(); + prop.put("mail.transport.protocol", "smtp"); + prop.put("mail.smtp.auth", true); + prop.put("mail.smtp.starttls.enable", "true"); + prop.put("mail.smtp.ssl.protocols", "TLSv1.2"); + prop.put("mail.smtp.starttls.required", "true"); + prop.put("mail.smtp.auth.login.disable", "true"); + prop.put("mail.smtp.host", configuration.getHost()); + prop.put("mail.smtp.port", String.valueOf(configuration.getPort())); + prop.put("mail.smtp.ssl.trust", configuration.getHost()); + return Session.getInstance(prop, new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(configuration.getUser(), configuration.getPassword()); + } + }); + } +} diff --git a/src/functions/newsletter-subscription/src/main/java/newsletter/subscription/MailConfiguration.java b/src/functions/newsletter-subscription/src/main/java/newsletter/subscription/MailConfiguration.java index a22ef0bb..1e38075a 100644 --- a/src/functions/newsletter-subscription/src/main/java/newsletter/subscription/MailConfiguration.java +++ b/src/functions/newsletter-subscription/src/main/java/newsletter/subscription/MailConfiguration.java @@ -1,34 +1,34 @@ -package newsletter.subscription; - -import io.micronaut.context.annotation.ConfigurationProperties; -import io.micronaut.core.bind.annotation.Bindable; - -import javax.validation.constraints.NotBlank; - -@ConfigurationProperties("smtp") -public interface MailConfiguration { - /** - * @return The SMTP user - */ - @NotBlank - String getUser(); - - /** - * @return The SMTP password - */ - @NotBlank - String getPassword(); - - /** - * @return The SMTP host - */ - @NotBlank - String getHost(); - - /** - * @return The SMTP port - */ - @Bindable(defaultValue = "587") - int getPort(); - -} +package newsletter.subscription; + +import io.micronaut.context.annotation.ConfigurationProperties; +import io.micronaut.core.bind.annotation.Bindable; + +import jakarta.validation.constraints.NotBlank; + +@ConfigurationProperties("smtp") +public interface MailConfiguration { + /** + * @return The SMTP user + */ + @NotBlank + String getUser(); + + /** + * @return The SMTP password + */ + @NotBlank + String getPassword(); + + /** + * @return The SMTP host + */ + @NotBlank + String getHost(); + + /** + * @return The SMTP port + */ + @Bindable(defaultValue = "587") + int getPort(); + +} diff --git a/src/functions/newsletter-subscription/src/main/java/newsletter/subscription/SubscribeRequest.java b/src/functions/newsletter-subscription/src/main/java/newsletter/subscription/SubscribeRequest.java index 7696c4ee..6e447f92 100644 --- a/src/functions/newsletter-subscription/src/main/java/newsletter/subscription/SubscribeRequest.java +++ b/src/functions/newsletter-subscription/src/main/java/newsletter/subscription/SubscribeRequest.java @@ -1,36 +1,36 @@ -/* - * Copyright 2021 original authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package newsletter.subscription; - -import io.micronaut.core.annotation.Introspected; - -@Introspected -public class SubscribeRequest { - - private String email; - - public SubscribeRequest(String email) { - this.email = email; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } -} +/* + * Copyright 2021 original authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package newsletter.subscription; + +import io.micronaut.serde.annotation.Serdeable; + +@Serdeable +public class SubscribeRequest { + + private String email; + + public SubscribeRequest(String email) { + this.email = email; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } +} diff --git a/src/functions/newsletter-subscription/src/test/java/newsletter/subscription/FunctionTest.java b/src/functions/newsletter-subscription/src/test/java/newsletter/subscription/FunctionTest.java index eeb5158b..f7e669c6 100644 --- a/src/functions/newsletter-subscription/src/test/java/newsletter/subscription/FunctionTest.java +++ b/src/functions/newsletter-subscription/src/test/java/newsletter/subscription/FunctionTest.java @@ -1,44 +1,44 @@ -package newsletter.subscription; - -import com.fnproject.fn.testing.FnTestingRule; -import io.micronaut.context.annotation.Factory; -import io.micronaut.context.annotation.Replaces; -import org.junit.jupiter.api.Test; - -import javax.inject.Singleton; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -@Factory -public class FunctionTest { - - @Test - public void testFunction() { - FnTestingRule rule = FnTestingRule.createDefault() - .addSharedClass(TestResult.class); - rule.givenEvent().withBody("foo@bar.com").enqueue(); - rule.thenRun(Function.class, "handleRequest"); - String result = rule.getOnlyResult().getBodyAsString(); - assertEquals("{\"messageId\":\"1111\"}", result); - assertEquals("Hello from Mushop", TestResult.lastSubject); - assertEquals("Thanks for confirming your subscription!", TestResult.lastBody); - assertEquals("foo@bar.com", TestResult.lastTo); - } - - @Replaces(JavaMailSender.class) - @Singleton - MailSender mailSender() { - return (to, subject, body) -> { - TestResult.lastTo = to; - TestResult.lastSubject = subject; - TestResult.lastBody = body; - return "1111"; - }; - } - - public static class TestResult { - public static String lastTo; - public static String lastSubject; - public static String lastBody; - } -} +package newsletter.subscription; + +import com.fnproject.fn.testing.FnTestingRule; +import io.micronaut.context.annotation.Factory; +import io.micronaut.context.annotation.Replaces; +import org.junit.jupiter.api.Test; + +import jakarta.inject.Singleton; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@Factory +public class FunctionTest { + + @Test + public void testFunction() { + FnTestingRule rule = FnTestingRule.createDefault() + .addSharedClass(TestResult.class); + rule.givenEvent().withBody("foo@bar.com").enqueue(); + rule.thenRun(Function.class, "handleRequest"); + String result = rule.getOnlyResult().getBodyAsString(); + assertEquals("{\"messageId\":\"1111\"}", result); + assertEquals("Hello from Mushop", TestResult.lastSubject); + assertEquals("Thanks for confirming your subscription!", TestResult.lastBody); + assertEquals("foo@bar.com", TestResult.lastTo); + } + + @Replaces(JavaMailSender.class) + @Singleton + MailSender mailSender() { + return (to, subject, body) -> { + TestResult.lastTo = to; + TestResult.lastSubject = subject; + TestResult.lastBody = body; + return "1111"; + }; + } + + public static class TestResult { + public static String lastTo; + public static String lastSubject; + public static String lastBody; + } +}