Files
spring-cloud-function/spring-cloud-function-samples/function-azure-di-samples/README.md
Christian Tzolov 3a297051e5 GH-968 Support Azure Functions DI hook
- Extend spring-cloud-function-adapter-azure with AzureFunctionInstanceInjector registered through the  META-INF/services/com.microsoft.azure.functions.spi.inject.FunctionInstanceInjector
 - Add DI demos for HttpTrigger and TimeTrigger functions.

 Resolves #968
 Resolves #969
Add FunctionInvoker backward compatibiity

document the time trigger DI sample

Add generic instructions to implement Azure Function with the help of the DI hook

Add generic instructions to implement Azure Function with the help of the DI hook

Minor

Fix injector backward compatibility and add blob demo

disable the azure di samples maven module builds
2022-12-15 11:00:41 +01:00

197 lines
5.8 KiB
Markdown

# 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 `2.7.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>3.2.9 or higher</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 `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"
},
}
```