add dependecy injection examples with Gooogle Juice and Dagger2 (#698)

This commit is contained in:
kaibocai 2023-02-10 13:41:15 -06:00 коммит произвёл GitHub
Родитель 79427b3b92
Коммит 385d93af4b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
24 изменённых файлов: 539 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,3 @@
## Dependency Injection Examples for Azure Java Functions
This rep contains examples that integrate Google Dagger2 and Google Juice with Azure Java Functions.

Просмотреть файл

@ -0,0 +1,15 @@
# azure-function-guice
Integration Google Dagger2 with Azure Functions
Utilize [com.microsoft.azure.functions.spi.inject.FunctionInstanceInjector](https://github.com/Azure/azure-functions-java-additions/blob/dev/azure-functions-java-spi/src/main/java/com/microsoft/azure/functions/spi/inject/FunctionInstanceInjector.java) provided by azure functions java worker to integrate Google Dagger2 framework into Azure Java Function.
## Local Setup
1. Clone the repo
2. Enter corresponding directory and run `mvn clean package` to build the project
3. Run `mvn azure-functions:run` to run the project on local.
Local example:
![img.png](img.png)
![img_1.png](img_1.png)
4. Run `mvn azure-functions:deploy` to deploy the function app, for more info about deploy azure function java app please refer to [deploy java function app](https://learn.microsoft.com/en-us/azure/azure-functions/create-first-function-cli-java?tabs=bash%2Cazure-cli%2Cbrowser#deploy-the-function-project-to-azure)

Просмотреть файл

@ -0,0 +1,7 @@
{
"version": "2.0",
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[3.*, 4.0.0)"
}
}

Двоичные данные
samples/dependency-injection-example/dagger-function/img.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.9 KiB

Двоичные данные
samples/dependency-injection-example/dagger-function/img_1.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 144 KiB

Просмотреть файл

@ -0,0 +1,130 @@
<?xml version="1.0" encoding="UTF-8" ?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.azfs.example</groupId>
<artifactId>dagger-function</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Azure Java Functions</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<azure.functions.maven.plugin.version>1.21.0</azure.functions.maven.plugin.version>
<azure.functions.java.library.version>2.0.1</azure.functions.java.library.version>
<functionAppName>dagger-function-20221101192648097</functionAppName>
</properties>
<dependencies>
<dependency>
<groupId>com.microsoft.azure.functions</groupId>
<artifactId>azure-functions-java-library</artifactId>
<version>${azure.functions.java.library.version}</version>
</dependency>
<dependency>
<groupId>com.google.dagger</groupId>
<artifactId>dagger</artifactId>
<version>2.44</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure.functions</groupId>
<artifactId>azure-functions-java-spi</artifactId>
<version>1.0.0</version>
<scope>provided</scope>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.4.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.23.4</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
<annotationProcessorPaths>
<path>
<groupId>com.google.dagger</groupId>
<artifactId>dagger-compiler</artifactId>
<version>2.16</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-functions-maven-plugin</artifactId>
<version>${azure.functions.maven.plugin.version}</version>
<configuration>
<!-- function app name -->
<appName>${functionAppName}</appName>
<!-- function app resource group -->
<resourceGroup>java-functions-group</resourceGroup>
<!-- function app service plan name -->
<appServicePlanName>java-functions-app-service-plan</appServicePlanName>
<!-- function app region-->
<!-- refers https://github.com/microsoft/azure-maven-plugins/wiki/Azure-Functions:-Configuration-Details#supported-regions for all valid values -->
<region>westus</region>
<!-- function pricingTier, default to be consumption if not specified -->
<!-- refers https://github.com/microsoft/azure-maven-plugins/wiki/Azure-Functions:-Configuration-Details#supported-pricing-tiers for all valid values -->
<!-- <pricingTier></pricingTier> -->
<!-- Whether to disable application insights, default is false -->
<!-- refers https://github.com/microsoft/azure-maven-plugins/wiki/Azure-Functions:-Configuration-Details for all valid configurations for application insights-->
<!-- <disableAppInsights></disableAppInsights> -->
<runtime>
<!-- runtime os, could be windows, linux or docker-->
<os>windows</os>
<javaVersion>8</javaVersion>
</runtime>
<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>
<!--Remove obj folder generated by .NET SDK in maven clean-->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<filesets>
<fileset>
<directory>obj</directory>
</fileset>
</filesets>
</configuration>
</plugin>
</plugins>
</build>
</project>

Просмотреть файл

@ -0,0 +1,55 @@
package com.azfs;
import com.azfs.model.Communicator;
import com.microsoft.azure.functions.ExecutionContext;
import com.microsoft.azure.functions.HttpMethod;
import com.microsoft.azure.functions.HttpRequestMessage;
import com.microsoft.azure.functions.HttpResponseMessage;
import com.microsoft.azure.functions.HttpStatus;
import com.microsoft.azure.functions.annotation.AuthorizationLevel;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.annotation.HttpTrigger;
import javax.inject.Inject;
import java.util.Optional;
/**
* Azure Functions with HTTP Trigger.
*/
public class Function {
/**
* This function listens at endpoint "/api/HttpExample". Two ways to invoke it using "curl" command in bash:
* 1. curl -d "HTTP Body" {your host}/api/HttpExample
* 2. curl "{your host}/api/HttpExample?name=HTTP%20Query"
*/
private final Communicator communicator;
@Inject
public Function(Communicator communicator) {
this.communicator = communicator;
}
@FunctionName("HttpExample")
public HttpResponseMessage run(
@HttpTrigger(
name = "req",
methods = {HttpMethod.GET, HttpMethod.POST},
authLevel = AuthorizationLevel.ANONYMOUS)
HttpRequestMessage<Optional<String>> request,
final ExecutionContext context) {
context.getLogger().info("Java HTTP trigger processed a request.");
// Parse query parameter
final String query = request.getQueryParameters().get("name");
final String name = request.getBody().orElse(query);
communicator.communicate(context);
if (name == null) {
return request.createResponseBuilder(HttpStatus.BAD_REQUEST).body("Please pass a name on the query string or in the request body").build();
} else {
return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + name).build();
}
}
}

Просмотреть файл

@ -0,0 +1,10 @@
package com.azfs.component;
import com.azfs.Function;
import com.azfs.module.FunctionModule;
import dagger.Component;
@Component(modules = FunctionModule.class)
public interface FunctionComponent {
Function buildFunction();
}

Просмотреть файл

@ -0,0 +1,11 @@
package com.azfs.dihook;
import com.azfs.component.DaggerFunctionComponent;
import com.microsoft.azure.functions.spi.inject.FunctionInstanceInjector;
public class MyFunctionInstanceInjector implements FunctionInstanceInjector {
@Override
public <T> T getInstance(Class<T> aClass) throws Exception {
return (T) DaggerFunctionComponent.create().buildFunction();
}
}

Просмотреть файл

@ -0,0 +1,16 @@
package com.azfs.model;
import com.microsoft.azure.functions.ExecutionContext;
public class Communicator {
private final String id;
public Communicator(String id) {
this.id = id;
}
public void communicate(ExecutionContext context){
context.getLogger().info("Message sent out from injected communicator :) ");
//add your own logics ...
}
}

Просмотреть файл

@ -0,0 +1,13 @@
package com.azfs.module;
import com.azfs.model.Communicator;
import dagger.Module;
import dagger.Provides;
@Module
public class FunctionModule {
@Provides
public Communicator provideCommunicator() {
return new Communicator("123");
}
}

Просмотреть файл

@ -0,0 +1 @@
com.azfs.dihook.MyFunctionInstanceInjector

39
samples/dependency-injection-example/guice-function/.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,39 @@
# Build output
target/
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
# IDE
.idea/
*.iml
.settings/
.project
.classpath
.vscode/
# macOS
.DS_Store
# Azure Functions
local.settings.json
bin/
obj/

Просмотреть файл

@ -0,0 +1,15 @@
# azure-function-guice
Integration Google Guice with Azure Functions
Utilize [com.microsoft.azure.functions.spi.inject.FunctionInstanceInjector](https://github.com/Azure/azure-functions-java-additions/blob/dev/azure-functions-java-spi/src/main/java/com/microsoft/azure/functions/spi/inject/FunctionInstanceInjector.java) provided by azure functions java worker to integrate Google Guice framework into Azure Java Function.
## Local Setup
1. Clone the repo
2. Enter corresponding directory and run `mvn clean package` to build the project
3. Run `mvn azure-functions:run` to run the project on local.
Local example:
![img.png](img.png)
![img_2.png](img_2.png)
4. Run `mvn azure-functions:deploy` to deploy the function app, for more info about deploy azure function java app please refer to [deploy java function app](https://learn.microsoft.com/en-us/azure/azure-functions/create-first-function-cli-java?tabs=bash%2Cazure-cli%2Cbrowser#deploy-the-function-project-to-azure)

Просмотреть файл

@ -0,0 +1,7 @@
{
"version": "2.0",
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[3.*, 4.0.0)"
}
}

Двоичные данные
samples/dependency-injection-example/guice-function/img.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.5 KiB

Двоичные данные
samples/dependency-injection-example/guice-function/img_2.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 139 KiB

Просмотреть файл

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="UTF-8" ?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.azfs.example</groupId>
<artifactId>juice-test</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Azure Java Functions</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<azure.functions.maven.plugin.version>1.19.0</azure.functions.maven.plugin.version>
<azure.functions.java.library.version>2.1.0</azure.functions.java.library.version>
<functionAppName>juice-test-20220912191553642</functionAppName>
</properties>
<dependencies>
<dependency>
<groupId>com.microsoft.azure.functions</groupId>
<artifactId>azure-functions-java-library</artifactId>
<version>${azure.functions.java.library.version}</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure.functions</groupId>
<artifactId>azure-functions-java-spi</artifactId>
<version>1.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.inject/guice -->
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>5.1.0</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.4.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.23.4</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-functions-maven-plugin</artifactId>
<version>${azure.functions.maven.plugin.version}</version>
<configuration>
<!-- function app name -->
<appName>${functionAppName}</appName>
<!-- function app resource group -->
<resourceGroup>java-functions-group</resourceGroup>
<!-- function app service plan name -->
<appServicePlanName>java-functions-app-service-plan</appServicePlanName>
<!-- function app region-->
<!-- refers https://github.com/microsoft/azure-maven-plugins/wiki/Azure-Functions:-Configuration-Details#supported-regions for all valid values -->
<region>westus</region>
<!-- function pricingTier, default to be consumption if not specified -->
<!-- refers https://github.com/microsoft/azure-maven-plugins/wiki/Azure-Functions:-Configuration-Details#supported-pricing-tiers for all valid values -->
<!-- <pricingTier></pricingTier> -->
<!-- Whether to disable application insights, default is false -->
<!-- refers https://github.com/microsoft/azure-maven-plugins/wiki/Azure-Functions:-Configuration-Details for all valid configurations for application insights-->
<!-- <disableAppInsights></disableAppInsights> -->
<runtime>
<!-- runtime os, could be windows, linux or docker-->
<os>windows</os>
<javaVersion>8</javaVersion>
</runtime>
<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>
<!--Remove obj folder generated by .NET SDK in maven clean-->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<filesets>
<fileset>
<directory>obj</directory>
</fileset>
</filesets>
</configuration>
</plugin>
</plugins>
</build>
</project>

Просмотреть файл

@ -0,0 +1,11 @@
package com.azfs;
import com.google.inject.AbstractModule;
public class BasicModule extends AbstractModule {
@Override
protected void configure() {
bind(Communicator.class).to(DefaultCommunicatorImpl.class);
}
}

Просмотреть файл

@ -0,0 +1,7 @@
package com.azfs;
import com.microsoft.azure.functions.ExecutionContext;
public interface Communicator {
boolean sendMessage(ExecutionContext context);
}

Просмотреть файл

@ -0,0 +1,12 @@
package com.azfs;
import com.microsoft.azure.functions.ExecutionContext;
public class DefaultCommunicatorImpl implements Communicator{
@Override
public boolean sendMessage(ExecutionContext context) {
context.getLogger().info("Message sent out from injected communicator :) ");
//add your own logic...
return true;
}
}

Просмотреть файл

@ -0,0 +1,51 @@
package com.azfs;
import com.google.inject.Inject;
import com.microsoft.azure.functions.ExecutionContext;
import com.microsoft.azure.functions.HttpMethod;
import com.microsoft.azure.functions.HttpRequestMessage;
import com.microsoft.azure.functions.HttpResponseMessage;
import com.microsoft.azure.functions.HttpStatus;
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;
/**
* Azure Functions with HTTP Trigger.
*/
public class Function {
/**
* This function listens at endpoint "/api/HttpExample". Two ways to invoke it using "curl" command in bash:
* 1. curl -d "HTTP Body" {your host}/api/HttpExample
* 2. curl "{your host}/api/HttpExample?name=HTTP%20Query"
*/
@Inject
public Communicator communicator;
@FunctionName("HttpExample")
public HttpResponseMessage run(
@HttpTrigger(
name = "req",
methods = {HttpMethod.GET, HttpMethod.POST},
authLevel = AuthorizationLevel.ANONYMOUS)
HttpRequestMessage<Optional<String>> request,
final ExecutionContext context) {
context.getLogger().info("Java HTTP trigger processed a request.");
// Parse query parameter
final String query = request.getQueryParameters().get("name");
final String name = request.getBody().orElse(query);
//use the injected communicator to send out message
communicator.sendMessage(context);
if (name == null) {
return request.createResponseBuilder(HttpStatus.BAD_REQUEST).body("Please pass a name on the query string or in the request body").build();
} else {
return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + name).build();
}
}
}

Просмотреть файл

@ -0,0 +1,12 @@
package com.azfs.dihook;
import com.google.inject.Guice;
import com.azfs.BasicModule;
import com.microsoft.azure.functions.spi.inject.FunctionInstanceInjector;
public class FunctionGuiceFactory implements FunctionInstanceInjector {
@Override
public <T> T getInstance(Class<T> functionClass) throws Exception {
return Guice.createInjector(new BasicModule()).getInstance(functionClass);
}
}

Просмотреть файл

@ -0,0 +1 @@
com.azfs.dihook.FunctionGuiceFactory