From 91b333acaf440df5d236e793445481bee1ee1667 Mon Sep 17 00:00:00 2001 From: Julien Dubois Date: Wed, 6 Dec 2023 11:20:31 +0100 Subject: [PATCH] Update the Spring Cloud Function sample to Spring Boot 3.2.0 and sync it with the documentation --- samples/spring-cloud-example/README.md | 50 +++++++++---------- samples/spring-cloud-example/pom.xml | 35 ++++--------- .../example/DemoApplication.java} | 23 ++++----- .../java/{ => com}/example/hello/Hello.java | 4 +- .../{ => com}/example/hello/HelloHandler.java | 10 ++-- .../hello => com/example}/model/Greeting.java | 2 +- .../hello => com/example}/model/User.java | 2 +- .../main/java/example/uppercase/Config.java | 30 ----------- .../java/example/uppercase/EchoHandler.java | 31 ------------ .../example/uppercase/UppercaseHandler.java | 36 ------------- .../src/main/resources/host.json | 5 +- .../hello => com/example}/HelloTest.java | 35 +++++++------ 12 files changed, 73 insertions(+), 190 deletions(-) rename samples/spring-cloud-example/src/main/java/{example/Application.java => com/example/DemoApplication.java} (60%) rename samples/spring-cloud-example/src/main/java/{ => com}/example/hello/Hello.java (83%) rename samples/spring-cloud-example/src/main/java/{ => com}/example/hello/HelloHandler.java (82%) rename samples/spring-cloud-example/src/main/java/{example/hello => com/example}/model/Greeting.java (91%) rename samples/spring-cloud-example/src/main/java/{example/hello => com/example}/model/User.java (90%) delete mode 100644 samples/spring-cloud-example/src/main/java/example/uppercase/Config.java delete mode 100644 samples/spring-cloud-example/src/main/java/example/uppercase/EchoHandler.java delete mode 100644 samples/spring-cloud-example/src/main/java/example/uppercase/UppercaseHandler.java rename samples/spring-cloud-example/src/test/java/{example/hello => com/example}/HelloTest.java (71%) diff --git a/samples/spring-cloud-example/README.md b/samples/spring-cloud-example/README.md index 7d2a595a..3b2464c3 100644 --- a/samples/spring-cloud-example/README.md +++ b/samples/spring-cloud-example/README.md @@ -15,7 +15,7 @@ To develop functions using Java, you must have the following installed: > [!IMPORTANT] > 1. You must set the JAVA_HOME environment variable to the install location of the JDK to complete this quickstart. -> 2. Make sure your core tools version is at least 4.0.5030 +> 2. Make sure your core tools version is at least 4.0.5455 ## What we're going to build @@ -46,19 +46,17 @@ Change those properties directly near the top of the *pom.xml* file, as shown in ```xml UTF-8 - 11 - 11 + 11 - 1.22.0 - 3.0.0 + + com.example.DemoApplication - + my-spring-function-resource-group my-spring-function-service-plan my-spring-function - - westeurope - example.Application + eastus + Y1 ``` @@ -74,7 +72,7 @@ Create a *src/main/azure* folder and add the following Azure Functions configura "version": "2.0", "extensionBundle": { "id": "Microsoft.Azure.Functions.ExtensionBundle", - "version": "[4.*, 5.0.0)" + "version": "[4.*, 5.2.0)" }, "functionTimeout": "00:10:00" } @@ -162,33 +160,32 @@ This capability gives you two main benefits over a standard Azure Function: - It doesn't rely on the Azure Functions APIs, so you can easily port it to other systems. For example, you can reuse it in a normal Spring Boot application. - You can use all the `@Enable` annotations from Spring Boot to add new features. -In the *src/main/java/example* folder, create the following file, which is a normal Spring Boot application: +In the *src/main/java/com/example* folder, create the following file, which is a normal Spring Boot application: *DemoApplication.java*: ```java -package example; +package com.example; -import example.uppercase.Config; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication -public class Application { +public class DemoApplication { public static void main(String[] args) throws Exception { - SpringApplication.run(Config.class, args); + SpringApplication.run(DemoApplication.class, args); } } ``` -Now create the following file *src/main/java/example/hello* folder, which contains a Spring Boot component that represents the Function we want to run: +Now create the following file *src/main/java/com/example/hello* folder, which contains a Spring Boot component that represents the Function we want to run: *Hello.java*: ```java -package example.hello; +package com.example.hello; -import example.hello.model.*; +import com.example.model.*; import org.springframework.stereotype.Component; import java.util.function.Function; @@ -217,13 +214,13 @@ In the *src/main/java/com/example/hello* folder, create the following Azure Func *HelloHandler.java*: ```java -package example.hello; +package com.example.hello; import com.microsoft.azure.functions.*; import com.microsoft.azure.functions.annotation.AuthorizationLevel; import com.microsoft.azure.functions.annotation.FunctionName; import com.microsoft.azure.functions.annotation.HttpTrigger; -import example.hello.model.*; +import com.example.model.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -237,14 +234,12 @@ public class HelloHandler { @FunctionName("hello") public HttpResponseMessage execute( - @HttpTrigger(name = "request", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage> request, - ExecutionContext context) { + @HttpTrigger(name = "request", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage> request, ExecutionContext context) { User user = request.getBody() .filter(u -> u.getName() != null) .orElseGet(() -> new User(request.getQueryParameters().getOrDefault("name", "world"))); context.getLogger().info("Greeting user name: " + user.getName()); - return request - .createResponseBuilder(HttpStatus.OK) + return request.createResponseBuilder(HttpStatus.OK) .body(hello.apply(user)) .header("Content-Type", "application/json") .build(); @@ -267,10 +262,11 @@ Create a *src/test/java/com/example* folder and add the following JUnit tests: *HelloTest.java*: ```java -package example.hello; +package com.example; -import example.hello.model.Greeting; -import example.hello.model.User; +import com.example.hello.Hello; +import com.example.model.Greeting; +import com.example.model.User; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/samples/spring-cloud-example/pom.xml b/samples/spring-cloud-example/pom.xml index 7e56a510..546b027d 100644 --- a/samples/spring-cloud-example/pom.xml +++ b/samples/spring-cloud-example/pom.xml @@ -5,11 +5,11 @@ org.springframework.boot spring-boot-starter-parent - 3.0.1-SNAPSHOT + 3.2.0 - com.example.azure.di + com.example azure-httptrigger-demo 0.0.1-SNAPSHOT azure-httptrigger-demo @@ -17,26 +17,25 @@ Demo Spring Boot, Azure Function - HttpTrigger (DI adapter) - 17 - 1.0.28.RELEASE + 11 - - example.Application + + com.example.DemoApplication - - 1.22.0 + + 1.29.0 spring-cloud-function-samples - westus sample-resource-group sample-service-plan - EP1 + Y1 + eastus org.springframework.cloud spring-cloud-function-adapter-azure - 4.0.0 + 4.0.5 @@ -48,7 +47,7 @@ org.junit.jupiter junit-jupiter-api - 5.9.2 + 5.10.1 test @@ -99,18 +98,6 @@ - - - org.springframework.boot - spring-boot-maven-plugin - - - org.springframework.boot.experimental - spring-boot-thin-layout - ${spring-boot-thin-layout.version} - - - diff --git a/samples/spring-cloud-example/src/main/java/example/Application.java b/samples/spring-cloud-example/src/main/java/com/example/DemoApplication.java similarity index 60% rename from samples/spring-cloud-example/src/main/java/example/Application.java rename to samples/spring-cloud-example/src/main/java/com/example/DemoApplication.java index 30bf4594..88184e0e 100644 --- a/samples/spring-cloud-example/src/main/java/example/Application.java +++ b/samples/spring-cloud-example/src/main/java/com/example/DemoApplication.java @@ -1,12 +1,11 @@ -package example; - -import example.uppercase.Config; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class Application { - public static void main(String[] args) throws Exception { - SpringApplication.run(Config.class, args); - } -} +package com.example; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DemoApplication { + public static void main(String[] args) throws Exception { + SpringApplication.run(DemoApplication.class, args); + } +} diff --git a/samples/spring-cloud-example/src/main/java/example/hello/Hello.java b/samples/spring-cloud-example/src/main/java/com/example/hello/Hello.java similarity index 83% rename from samples/spring-cloud-example/src/main/java/example/hello/Hello.java rename to samples/spring-cloud-example/src/main/java/com/example/hello/Hello.java index f3e71890..05b88c7e 100644 --- a/samples/spring-cloud-example/src/main/java/example/hello/Hello.java +++ b/samples/spring-cloud-example/src/main/java/com/example/hello/Hello.java @@ -1,6 +1,6 @@ -package example.hello; +package com.example.hello; -import example.hello.model.*; +import com.example.model.*; import org.springframework.stereotype.Component; import java.util.function.Function; diff --git a/samples/spring-cloud-example/src/main/java/example/hello/HelloHandler.java b/samples/spring-cloud-example/src/main/java/com/example/hello/HelloHandler.java similarity index 82% rename from samples/spring-cloud-example/src/main/java/example/hello/HelloHandler.java rename to samples/spring-cloud-example/src/main/java/com/example/hello/HelloHandler.java index a2dd39fa..f8c185a9 100644 --- a/samples/spring-cloud-example/src/main/java/example/hello/HelloHandler.java +++ b/samples/spring-cloud-example/src/main/java/com/example/hello/HelloHandler.java @@ -1,10 +1,10 @@ -package example.hello; +package com.example.hello; import com.microsoft.azure.functions.*; import com.microsoft.azure.functions.annotation.AuthorizationLevel; import com.microsoft.azure.functions.annotation.FunctionName; import com.microsoft.azure.functions.annotation.HttpTrigger; -import example.hello.model.*; +import com.example.model.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -18,14 +18,12 @@ public class HelloHandler { @FunctionName("hello") public HttpResponseMessage execute( - @HttpTrigger(name = "request", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage> request, - ExecutionContext context) { + @HttpTrigger(name = "request", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage> request, ExecutionContext context) { User user = request.getBody() .filter(u -> u.getName() != null) .orElseGet(() -> new User(request.getQueryParameters().getOrDefault("name", "world"))); context.getLogger().info("Greeting user name: " + user.getName()); - return request - .createResponseBuilder(HttpStatus.OK) + return request.createResponseBuilder(HttpStatus.OK) .body(hello.apply(user)) .header("Content-Type", "application/json") .build(); diff --git a/samples/spring-cloud-example/src/main/java/example/hello/model/Greeting.java b/samples/spring-cloud-example/src/main/java/com/example/model/Greeting.java similarity index 91% rename from samples/spring-cloud-example/src/main/java/example/hello/model/Greeting.java rename to samples/spring-cloud-example/src/main/java/com/example/model/Greeting.java index 66ebe82b..5376dea0 100644 --- a/samples/spring-cloud-example/src/main/java/example/hello/model/Greeting.java +++ b/samples/spring-cloud-example/src/main/java/com/example/model/Greeting.java @@ -1,4 +1,4 @@ -package example.hello.model; +package com.example.model; public class Greeting { diff --git a/samples/spring-cloud-example/src/main/java/example/hello/model/User.java b/samples/spring-cloud-example/src/main/java/com/example/model/User.java similarity index 90% rename from samples/spring-cloud-example/src/main/java/example/hello/model/User.java rename to samples/spring-cloud-example/src/main/java/com/example/model/User.java index e6d859a3..867c19ec 100644 --- a/samples/spring-cloud-example/src/main/java/example/hello/model/User.java +++ b/samples/spring-cloud-example/src/main/java/com/example/model/User.java @@ -1,4 +1,4 @@ -package example.hello.model; +package com.example.model; public class User { diff --git a/samples/spring-cloud-example/src/main/java/example/uppercase/Config.java b/samples/spring-cloud-example/src/main/java/example/uppercase/Config.java deleted file mode 100644 index 571dbc29..00000000 --- a/samples/spring-cloud-example/src/main/java/example/uppercase/Config.java +++ /dev/null @@ -1,30 +0,0 @@ -package example.uppercase; - -import java.util.Map; -import java.util.function.Function; - -import com.microsoft.azure.functions.ExecutionContext; -import org.springframework.context.annotation.Configuration; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.function.json.JsonMapper; -import org.springframework.context.annotation.Bean; -import org.springframework.messaging.Message; - -@Configuration -public class Config { - - @Bean - public Function echo() { - return payload -> payload; - } - - @Bean - public Function uppercase() { - return payload -> payload.toUpperCase(); - } -} - diff --git a/samples/spring-cloud-example/src/main/java/example/uppercase/EchoHandler.java b/samples/spring-cloud-example/src/main/java/example/uppercase/EchoHandler.java deleted file mode 100644 index c07ff166..00000000 --- a/samples/spring-cloud-example/src/main/java/example/uppercase/EchoHandler.java +++ /dev/null @@ -1,31 +0,0 @@ -package example.uppercase; - -import com.microsoft.azure.functions.ExecutionContext; -import com.microsoft.azure.functions.HttpMethod; -import com.microsoft.azure.functions.HttpRequestMessage; -import com.microsoft.azure.functions.annotation.AuthorizationLevel; -import com.microsoft.azure.functions.annotation.FunctionName; -import com.microsoft.azure.functions.annotation.HttpTrigger; - -import java.util.Optional; -import java.util.function.Function; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cloud.function.adapter.azure.FunctionInvoker; -import org.springframework.messaging.Message; -import org.springframework.messaging.support.MessageBuilder; -import org.springframework.stereotype.Component; - -@Component -public class EchoHandler { - - @Autowired - private Function echo; - - @FunctionName("echo") - public String execute(@HttpTrigger(name = "req", methods = {HttpMethod.GET, - HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage> request, - ExecutionContext context) { - return echo.apply(request.getBody().get()); - } -} diff --git a/samples/spring-cloud-example/src/main/java/example/uppercase/UppercaseHandler.java b/samples/spring-cloud-example/src/main/java/example/uppercase/UppercaseHandler.java deleted file mode 100644 index 0a379b92..00000000 --- a/samples/spring-cloud-example/src/main/java/example/uppercase/UppercaseHandler.java +++ /dev/null @@ -1,36 +0,0 @@ -package example.uppercase; - -import com.microsoft.azure.functions.ExecutionContext; -import com.microsoft.azure.functions.HttpMethod; -import com.microsoft.azure.functions.HttpRequestMessage; -import com.microsoft.azure.functions.annotation.AuthorizationLevel; -import com.microsoft.azure.functions.annotation.FunctionName; -import com.microsoft.azure.functions.annotation.HttpTrigger; - -import java.util.Optional; -import java.util.function.Function; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cloud.function.adapter.azure.FunctionInvoker; -import org.springframework.messaging.Message; -import org.springframework.messaging.support.MessageBuilder; -import org.springframework.stereotype.Component; - -@Component -public class UppercaseHandler { - - @Autowired - private Function uppercase; - - @FunctionName("uppercase") - public String execute( - @HttpTrigger( - name = "req", - methods = {HttpMethod.GET, HttpMethod.POST}, - authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage> request, - ExecutionContext context - ) { - context.getLogger().warning("Using Java (" + System.getProperty("java.version") + ")"); - return uppercase.apply(request.getBody().get()); - } -} diff --git a/samples/spring-cloud-example/src/main/resources/host.json b/samples/spring-cloud-example/src/main/resources/host.json index b713a6d8..865badcc 100644 --- a/samples/spring-cloud-example/src/main/resources/host.json +++ b/samples/spring-cloud-example/src/main/resources/host.json @@ -2,6 +2,7 @@ "version": "2.0", "extensionBundle": { "id": "Microsoft.Azure.Functions.ExtensionBundle", - "version": "[4.*, 5.0.0)" - } + "version": "[4.*, 5.2.0)" + }, + "functionTimeout": "00:10:00" } diff --git a/samples/spring-cloud-example/src/test/java/example/hello/HelloTest.java b/samples/spring-cloud-example/src/test/java/com/example/HelloTest.java similarity index 71% rename from samples/spring-cloud-example/src/test/java/example/hello/HelloTest.java rename to samples/spring-cloud-example/src/test/java/com/example/HelloTest.java index 084de9bd..35e000b5 100644 --- a/samples/spring-cloud-example/src/test/java/example/hello/HelloTest.java +++ b/samples/spring-cloud-example/src/test/java/com/example/HelloTest.java @@ -1,18 +1,17 @@ -package example.hello; - - -import example.hello.model.Greeting; -import example.hello.model.User; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - - -public class HelloTest { - - @Test - public void test() { - Greeting result = new Hello().apply(new User("foo")); - assertThat(result.getMessage()).isEqualTo("Hello, foo!\n"); - } -} +package com.example; + +import com.example.hello.Hello; +import com.example.model.Greeting; +import com.example.model.User; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class HelloTest { + + @Test + public void test() { + Greeting result = new Hello().apply(new User("foo")); + assertThat(result.getMessage()).isEqualTo("Hello, foo!\n"); + } +}