Azure samples version and code adjustments
This commit is contained in:
@@ -9,6 +9,16 @@ The Blob storage binding is part of an https://learn.microsoft.com/en-us/azure/a
|
||||
|
||||
=== Usage
|
||||
|
||||
For local Azure Storage development you need https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite?tabs=visual-studio[Azurite emulator].
|
||||
For the emulator you can run a docker container (see below) or use the https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite?tabs=visual-studio-code[Visual-Studio-Code extension].
|
||||
|
||||
Here is how to start the `Azure emulator` as docker container:
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
docker run --name azurite --rm -p 10000:10000 -p 10001:10001 -p 10002:10002 mcr.microsoft.com/azure-storage/azurite
|
||||
----
|
||||
|
||||
==== Package Staging folder
|
||||
|
||||
Use the script below to package your staging folder:
|
||||
@@ -27,11 +37,14 @@ Use the script below to run the function locally.
|
||||
./mvnw azure-functions:run
|
||||
----
|
||||
|
||||
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 https://docs.microsoft.com/en-us/azure/azure-functions/create-first-function-cli-java?tabs=bash%2Cazure-cli%2Cbrowser#configure-your-local-environment[here]).
|
||||
Use the https://azure.microsoft.com/en-us/products/storage/storage-explorer/[Azure Storage Explorer] to access the Emulator Storage Account.
|
||||
|
||||
NOTE: https://github.com/Azure/azure-functions-core-tools[Azure Functions Core Tools] version `4.0.5030` or newer is required!
|
||||
Under the `Blob Containers` create 3 new containers: `test-trigger`, `test-input`, `test-output`.
|
||||
Then upload the `src/test/resource/sample.txt` file into the `test-input` and the `test-trigger` folders in this order.
|
||||
|
||||
For some configuration you would need the https://learn.microsoft.com/en-us/azure/storage/common/storage-use-emulator[Azurite emulator] as well.
|
||||
The appearance of the `sample.txt` file in the `test-trigger` folder triggers the `blobTest` function handler, that would look up for a file with the same name (because we used the `{name}` convention in the @BlobInput path) from the `test-input` folder.
|
||||
Later is passed through the auto-wired `uppercase` service and the result is saved in the `test-output` folder.
|
||||
Verify that the newly created file in `test-output` is in capitalized letters.
|
||||
|
||||
|
||||
==== Deploy Azure Functions to Azure Cloud
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.0.7</version>
|
||||
<version>3.1.1</version>
|
||||
<relativePath/>
|
||||
<!-- lookup parent from repository -->
|
||||
</parent>
|
||||
@@ -33,7 +33,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-function-adapter-azure</artifactId>
|
||||
<version>4.0.0</version>
|
||||
<version>4.0.5-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -30,7 +30,7 @@ public class AzureBlobTriggerDemoApplication {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Function<String, String> uppercase() {
|
||||
return payload -> payload.toUpperCase();
|
||||
public Function<byte[], byte[]> uppercase() {
|
||||
return payload -> new String(payload).toUpperCase().getBytes();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,33 +33,33 @@ import org.springframework.stereotype.Component;
|
||||
/**
|
||||
* Azure Functions with Azure Storage Blob.
|
||||
* https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-blob-trigger?tabs=java
|
||||
*
|
||||
* The Blob storage binding is part of an extension bundle, which is specified in your host.json project file.
|
||||
*
|
||||
* The Blob storage binding is part of an extension bundle, which is specified in your host.json project file.
|
||||
*/
|
||||
|
||||
@Component
|
||||
public class MyBlobFunction {
|
||||
|
||||
|
||||
@Autowired
|
||||
private Function<String, String> uppercase;
|
||||
private Function<byte[], byte[]> uppercase;
|
||||
|
||||
/**
|
||||
* This function will be invoked when a new or updated blob is detected at the specified path. The blob contents are
|
||||
* provided as input to this function. The location of the blob is provided in the path parameter. Example -
|
||||
* test-triggerinput-java/{name} below
|
||||
* test-trigger/{name} below
|
||||
*/
|
||||
@FunctionName("BlobTrigger")
|
||||
@StorageAccount("AzureWebJobsStorage")
|
||||
public void BlobTriggerToBlobTest(
|
||||
@BlobTrigger(name = "triggerBlob", path = "test-triggerinput-java/{name}", dataType = "binary") byte[] triggerBlob,
|
||||
public void blobTest(
|
||||
@BlobTrigger(name = "triggerBlob", path = "test-trigger/{name}", dataType = "binary") byte[] triggerBlob,
|
||||
@BindingName("name") String fileName,
|
||||
@BlobInput(name = "inputBlob", path = "test-input-java/{name}", dataType = "binary") byte[] inputBlob,
|
||||
@BlobOutput(name = "outputBlob", path = "test-output-java/{name}", dataType = "binary") OutputBinding<byte[]> outputBlob,
|
||||
@BlobInput(name = "inputBlob", path = "test-input/{name}", dataType = "binary") byte[] inputBlob,
|
||||
@BlobOutput(name = "outputBlob", path = "test-output/{name}", dataType = "binary") OutputBinding<byte[]> outputBlob,
|
||||
final ExecutionContext context) {
|
||||
|
||||
context.getLogger().info("Java Blob trigger function BlobTriggerToBlobTest processed a blob.\n Name: "
|
||||
|
||||
context.getLogger().info("Java Blob trigger function blobTest processed a blob.\n Name: "
|
||||
+ fileName + "\n Size: " + triggerBlob.length + " Bytes");
|
||||
outputBlob.setValue(inputBlob);
|
||||
|
||||
outputBlob.setValue(uppercase.apply(inputBlob));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
Authoritarianism begins when we can no longer tell the difference between the true and the appealing.
|
||||
At the same time, the cynic who decides that there is no truth at all is the citizen who welcomes the tyrant.
|
||||
― Timothy Snyder, The Road to Unfreedom
|
||||
@@ -35,6 +35,8 @@ should trigger an output like: `LOW CASE TEST%`
|
||||
|
||||
TIP: To debug your functions, please add `localDebug = "transport=dt_socket,server=y,suspend=n,address=5005"` to the `azurefunctions` section of your `build.gradle`.
|
||||
|
||||
IMPORTANT: After completing the sample run `./gradlew clean` to clean the hanging `azure-functions-java-worker.jar` processes.
|
||||
|
||||
==== Deploy Azure Functions to Azure Cloud
|
||||
|
||||
[source,shell]
|
||||
|
||||
@@ -28,12 +28,13 @@ jar {
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter'
|
||||
implementation "org.springframework.cloud:spring-cloud-function-adapter-azure:4.0.3"
|
||||
implementation "org.springframework.cloud:spring-cloud-function-adapter-azure:4.0.5-SNAPSHOT"
|
||||
}
|
||||
|
||||
tasks.named('test') {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.0.7</version>
|
||||
<version>3.1.1</version>
|
||||
<relativePath/>
|
||||
<!-- lookup parent from repository -->
|
||||
</parent>
|
||||
@@ -36,7 +36,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-function-adapter-azure</artifactId>
|
||||
<version>4.1.0-SNAPSHOT</version>
|
||||
<version>4.0.5-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.0.7</version>
|
||||
<version>3.1.1</version>
|
||||
<relativePath/>
|
||||
<!-- lookup parent from repository -->
|
||||
</parent>
|
||||
@@ -16,8 +16,8 @@
|
||||
<description>Demo project for Spring Boot</description>
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
<spring-cloud-function-dependencies.version>4.0.4</spring-cloud-function-dependencies.version>
|
||||
<azure.functions.java.core.version>3.0.0</azure.functions.java.core.version>
|
||||
<spring-cloud-function-dependencies.version>4.0.5-SNAPSHOT</spring-cloud-function-dependencies.version>
|
||||
<spring-boot-thin-layout.version>1.0.28.RELEASE</spring-boot-thin-layout.version>
|
||||
|
||||
<start-class>example.KafkaTriggerDemoApplication</start-class>
|
||||
|
||||
@@ -33,28 +33,14 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-function-context</artifactId>
|
||||
<version>${spring-cloud-function-dependencies.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>spring-cloud-function-adapter-azure</artifactId>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-function-adapter-azure</artifactId>
|
||||
<version>${spring-cloud-function-dependencies.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-function-dependencies</artifactId>
|
||||
<version>${spring-cloud-function-dependencies.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.azure.functions</groupId>
|
||||
<artifactId>azure-functions-java-library</artifactId>
|
||||
<version>${azure.functions.java.core.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
@@ -104,10 +90,17 @@
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- <plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin> -->
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot.experimental</groupId>
|
||||
<artifactId>spring-boot-thin-layout</artifactId>
|
||||
<version>${spring-boot-thin-layout.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
@@ -18,7 +18,6 @@ package example;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.microsoft.azure.functions.ExecutionContext;
|
||||
import example.entity.KafkaEntity;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package example;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.microsoft.azure.functions.BrokerAuthenticationMode;
|
||||
import com.microsoft.azure.functions.BrokerProtocol;
|
||||
import com.microsoft.azure.functions.ExecutionContext;
|
||||
@@ -24,35 +26,39 @@ import com.microsoft.azure.functions.annotation.FunctionName;
|
||||
import com.microsoft.azure.functions.annotation.KafkaOutput;
|
||||
import com.microsoft.azure.functions.annotation.KafkaTrigger;
|
||||
|
||||
import org.springframework.cloud.function.adapter.azure.FunctionInvoker;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
public class UppercaseHandler extends FunctionInvoker<Message<String>, String> {
|
||||
@Component
|
||||
public class UppercaseHandler {
|
||||
|
||||
@Autowired
|
||||
private Function<Message<String>, String> uppercase;
|
||||
|
||||
|
||||
@FunctionName("KafkaTrigger")
|
||||
public void execute(
|
||||
@KafkaTrigger(
|
||||
name = "KafkaTrigger",
|
||||
topic = "%TriggerKafkaTopic%",
|
||||
brokerList = "%BrokerList%",
|
||||
consumerGroup = "$Default",
|
||||
username = "%ConfluentCloudUsername%",
|
||||
password = "%ConfluentCloudPassword%",
|
||||
authenticationMode = BrokerAuthenticationMode.PLAIN,
|
||||
name = "KafkaTrigger",
|
||||
topic = "%TriggerKafkaTopic%",
|
||||
brokerList = "%BrokerList%",
|
||||
consumerGroup = "$Default",
|
||||
username = "%ConfluentCloudUsername%",
|
||||
password = "%ConfluentCloudPassword%",
|
||||
authenticationMode = BrokerAuthenticationMode.PLAIN,
|
||||
protocol = BrokerProtocol.PLAINTEXT,
|
||||
// protocol = BrokerProtocol.SASLSSL,
|
||||
// sslCaLocation = "confluent_cloud_cacert.pem", // Enable this line for windows.
|
||||
dataType = "string") String kafkaEventData,
|
||||
@KafkaOutput(
|
||||
name = "kafkaOutput",
|
||||
topic = "output",
|
||||
topic = "output",
|
||||
brokerList="%BrokerList%",
|
||||
username = "%ConfluentCloudUsername%",
|
||||
username = "%ConfluentCloudUsername%",
|
||||
password = "%ConfluentCloudPassword%",
|
||||
authenticationMode = BrokerAuthenticationMode.PLAIN,
|
||||
// sslCaLocation = "confluent_cloud_cacert.pem", // Enable this line for windows.
|
||||
// sslCaLocation = "confluent_cloud_cacert.pem", // Enable this line for windows.
|
||||
protocol = BrokerProtocol.PLAINTEXT
|
||||
// protocol = BrokerProtocol.SASLSSL
|
||||
) OutputBinding<String> output,
|
||||
@@ -62,7 +68,7 @@ public class UppercaseHandler extends FunctionInvoker<Message<String>, String> {
|
||||
|
||||
Message<String> message = MessageBuilder.withPayload(kafkaEventData).build();
|
||||
|
||||
String response = handleRequest(message, context);
|
||||
String response = uppercase.apply(message);
|
||||
|
||||
output.setValue(response);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.0.7</version>
|
||||
<version>3.1.1</version>
|
||||
<relativePath/>
|
||||
<!-- lookup parent from repository -->
|
||||
</parent>
|
||||
@@ -34,7 +34,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-function-adapter-azure</artifactId>
|
||||
<version>4.0.0</version>
|
||||
<version>4.0.5-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.0.7</version>
|
||||
<version>3.1.1</version>
|
||||
<relativePath/>
|
||||
<!-- lookup parent from repository -->
|
||||
</parent>
|
||||
@@ -20,7 +20,7 @@
|
||||
<java.version>17</java.version>
|
||||
|
||||
<spring-boot-thin-layout.version>1.0.28.RELEASE</spring-boot-thin-layout.version>
|
||||
<spring-cloud-function-adapter-azure-web.version>4.1.0-SNAPSHOT</spring-cloud-function-adapter-azure-web.version>
|
||||
<spring-cloud-function-adapter-azure-web.version>4.0.5-SNAPSHOT</spring-cloud-function-adapter-azure-web.version>
|
||||
|
||||
<!-- 2. You must set the Spring Boot start class for the Azure Function runtime to be able to find the entry point. -->
|
||||
<start-class>com.example.azure.web.AzureWebDemoApplication</start-class>
|
||||
|
||||
Reference in New Issue
Block a user