Forward port #969
This commit is contained in:
@@ -0,0 +1,206 @@
|
||||
# Azure Functions with DI adapter
|
||||
|
||||
## Common instructions to integrate Azure Functions with Spring Framework
|
||||
|
||||
* Use the [Spring Initializer](https://start.spring.io/) to generate a pain, java Spring Boot project without additional dependencies. Set the boot version to `3.0.x`, the build to `Maven` and the packaging to `Jar`.
|
||||
|
||||
* Add the `spring-cloud-function-adapter-azure` POM dependency:
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-function-adapter-azure</artifactId>
|
||||
<version>4.0.0</version>
|
||||
</dependency>
|
||||
```
|
||||
Having the adapter on the classpath activates the Azure Java Worker integration.
|
||||
|
||||
* Implement the [Azure Java Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-java?tabs=bash%2Cconsumption#java-function-basics) as `@FunctionName` annotated methods:
|
||||
|
||||
```java
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
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 org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class MyAzureFunction {
|
||||
|
||||
@Autowired
|
||||
private Function<String, String> uppercase;
|
||||
|
||||
@FunctionName("ditest")
|
||||
public String execute(
|
||||
@HttpTrigger(name = "req", methods = { HttpMethod.GET,
|
||||
HttpMethod.POST }, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
|
||||
ExecutionContext context) {
|
||||
|
||||
return this.uppercase.apply(request.getBody().get());
|
||||
}
|
||||
}
|
||||
```
|
||||
- The `@FunctionName` annotated methods represent the Azure Function implementations.
|
||||
- The class must be marked with the Spring `@Component` annotation.
|
||||
- You can use any Spring mechanism to auto-wire the Spring beans used for the function implementation.
|
||||
|
||||
* Add the `host.json` configuration under the `src/main/resources` folder:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "2.0",
|
||||
"extensionBundle": {
|
||||
"id": "Microsoft.Azure.Functions.ExtensionBundle",
|
||||
"version": "[3.*, 4.0.0)"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
* When bootstrapped as Spring Boot project make sure to either disable the `spring-boot-maven-plugin` plugin or cover it into `thin-layout`:
|
||||
|
||||
```xml
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot.experimental</groupId>
|
||||
<artifactId>spring-boot-thin-layout</artifactId>
|
||||
<version>${spring-boot-thin-layout.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
```
|
||||
Since Azure Functions requires a specific, custom, Jar packaging we have to disable SpringBoot one.
|
||||
|
||||
* Add the `start-class` POM property to point to your main (e.g. SpringApplication) class.
|
||||
```xml
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
<start-class>YOUR MAIN CLASS</start-class>
|
||||
...
|
||||
</properties>
|
||||
```
|
||||
|
||||
* Add the `azure-functions-maven-plugin` to your POM configuration. A sample configuration would look like this.
|
||||
|
||||
```xml
|
||||
<plugin>
|
||||
<groupId>com.microsoft.azure</groupId>
|
||||
<artifactId>azure-functions-maven-plugin</artifactId>
|
||||
<version>1.22.0 or higher</version>
|
||||
|
||||
<configuration>
|
||||
<appName>YOUR-AZURE-FUNCTION-APP-NAME</appName>
|
||||
<resourceGroup>YOUR-AZURE-FUNCTION-RESOURCE-GROUP</resourceGroup>
|
||||
<region>YOUR-AZURE-FUNCTION-APP-REGION</region>
|
||||
<appServicePlanName>YOUR-AZURE-FUNCTION-APP-SERVICE-PLANE-NAME</appServicePlanName>
|
||||
<pricingTier>YOUR-AZURE-FUNCTION-PRICING-TIER</pricingTier>
|
||||
|
||||
<hostJson>${project.basedir}/src/main/resources/host.json</hostJson>
|
||||
|
||||
<runtime>
|
||||
<os>linux</os>
|
||||
<javaVersion>11</javaVersion>
|
||||
</runtime>
|
||||
|
||||
<funcPort>7072</funcPort>
|
||||
|
||||
<appSettings>
|
||||
<property>
|
||||
<name>FUNCTIONS_EXTENSION_VERSION</name>
|
||||
<value>~4</value>
|
||||
</property>
|
||||
</appSettings>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>package-functions</id>
|
||||
<goals>
|
||||
<goal>package</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
```
|
||||
- Set the AZURE subscription configuration such as app name, resource group, region, service plan, pricing Tier
|
||||
- Runtime configuration:
|
||||
- [Java Versions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-java?tabs=bash%2Cconsumption#java-versions)
|
||||
- Specify [Deployment OS](https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-java?tabs=bash%2Cconsumption#specify-the-deployment-os)
|
||||
|
||||
* Build the project:
|
||||
|
||||
```
|
||||
./mvnw clean package
|
||||
```
|
||||
|
||||
## Running Locally
|
||||
|
||||
NOTE: To run locally on top of `Azure Functions`, and to deploy to your live Azure environment, you will need `Azure Functions Core Tools` installed along with the Azure CLI (see [here](https://docs.microsoft.com/en-us/azure/azure-functions/create-first-function-cli-java?tabs=bash%2Cazure-cli%2Cbrowser#configure-your-local-environment)).
|
||||
For some configuration you would need the [Azurite emulator](https://learn.microsoft.com/en-us/azure/storage/common/storage-use-emulator) as well.
|
||||
|
||||
Then build and run the sample:
|
||||
|
||||
```
|
||||
./mvnw clean package
|
||||
./mvnw azure-functions:run
|
||||
```
|
||||
|
||||
## Running on Azure
|
||||
|
||||
Make sure you are logged in your Azure account.
|
||||
```
|
||||
az login
|
||||
```
|
||||
|
||||
Build and deploy
|
||||
|
||||
```
|
||||
./mvnw clean package
|
||||
./mvnw azure-functions:deploy
|
||||
```
|
||||
|
||||
## Debug locally
|
||||
|
||||
Run the function in debug mode.
|
||||
```
|
||||
./mvnw azure-functions:deploy -DenableDebug
|
||||
```
|
||||
|
||||
Alternatively and the `JAVA_OPTS` value to your `local.settings.json` like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"IsEncrypted": false,
|
||||
"Values": {
|
||||
...
|
||||
"FUNCTIONS_WORKER_RUNTIME": "java",
|
||||
"JAVA_OPTS": "-Djava.net.preferIPv4Stack=true -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=127.0.0.1:5005"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
VS Code remote debug configuration:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "java",
|
||||
"name": "Attach to Remote Program",
|
||||
"request": "attach",
|
||||
"hostName": "localhost",
|
||||
"port": "5005"
|
||||
},
|
||||
}
|
||||
|
||||
```
|
||||
Reference in New Issue
Block a user