Azure Functions with DI adapter
Common instructions to integrate Azure Functions with Spring Framework
-
Use the Spring Initializer to generate a pain, java Spring Boot project without additional dependencies. Set the boot version to
3.0.x, the build toMavenand the packaging toJar. -
Add the
spring-cloud-function-adapter-azurePOM dependency:<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 as
@FunctionNameannotated methods: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
@FunctionNameannotated methods represent the Azure Function implementations. - The class must be marked with the Spring
@Componentannotation. - You can use any Spring mechanism to auto-wire the Spring beans used for the function implementation.
- The
-
Add the
host.jsonconfiguration under thesrc/main/resourcesfolder:{ "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-pluginplugin or cover it intothin-layout:<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-classPOM property to point to your main (e.g. SpringApplication) class.<properties> <java.version>17</java.version> <start-class>YOUR MAIN CLASS</start-class> ... </properties> -
Add the
azure-functions-maven-pluginto your POM configuration. A sample configuration would look like this.<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
- Specify 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).
NOTE: Azure Functions Core Tools version 4.0.5030 or newer is required!
For some configuration you would need the Azurite 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:
{
"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"
},
}
```