This sample demonstrates processing data from Azure Blob Storage using Java.
A function is made up of the code and the config. (function.json
).
For scripting languages (like JavaScript) the file has to be created manually, but for compiled languages (like Java) it is generated automatically from the annotations.
If you run ./gradlew azureFunctionsPackage
you will find the file at
build/azure-functions/{project-name}/{function-name}/function.json
The host.json
contains global configurations. However, this sample uses the absolute minimum to get it working.
See the Functions Developer guide for further info and any definitions that might be missing.
See the Java Function Reference for Java specifics.
Azure Blob Storage is essentially a cloud filesystem, but not in the usual sense that you would be used to.
There is a lot more to it than that, which you can read in the docs, but this oversimplification should be enough to conceptualise the demo.
The blob storage is structured in the following way:
Storage Account -> Container -> Blob
Accounts give you a unique namespace for your data.
Containers are like directories in a filesystem, however, you can't have a container within a container.
Blobs are files.
A storage account can include an unlimited number of containers, and a container can store an unlimited number of blobs.
For this simple demo we don't need to worry about the types of blobs as "Block blobs" are suitable for the text and binary data that we will deal with.
The BlobTrigger contains a path to the blobs inside a storage account.
@BlobTrigger(.....
path = "documents/{name}",
.....)
In this case the container is called documents
and the {name}
is the parameter that passes the blob name to the function.
When a new blob is created inside a container, the BlobTrigger is fired. If the Function is not running when the blob is added, the event will be queued until the Function starts again so that you don't miss any events.
Several steps are required to test and develop locally, and it won't work immediately on checkout without them.
Install Azurite to emulate the Azure Storage and enable local development.
Installing it using a VSCode extension sounds a bit weird, but it is simple to do and gives you an easier way to start and stop it.
Install Azure Storage Explorer to browse the storage.
It is probably best to use the snap package to install this on Ubuntu, so you don't have to install .NET.
NOTE: Azure Storage Explorer only works with gnome-keyring and not any other password managers such as KWallet
sudo apt install gnome-keyring
sudo snap connect storage-explorer:password-manager-service :password-manager-service
Azurite: From VSCode you can either click the [Azure Blob Service]
AND the [Azure Queue Service]
at the bottom of the window to start the service, or you can press F1 to open the command palette and type Azurite: Start
Azure Storage Explorer: On first start it will open the Connect Dialog and at the bottom you can select Local storage emulator
.
You can leave the defaults or change the Display Name if you wish.
In Azure Storage Explorer expand Storage Accounts and find the account in the list that matches the display name you just created.
NOTE: The (Attached Containers)
account is not what you want!
Under the account you will see Blob Containers
, right-click on this and Create Blob Container
.
Name it documents
to match the code example.
The Java code refers to a connection:
@FunctionName("blobTrigger")
public void blobTrigger(
@BlobTrigger(
name = "file",
dataType = "binary",
path = "documents/{name}",
connection = "AzureWebJobsStorage"
In order to connect this to Azurite, modify the local.settings.json
to have "AzureWebJobsStorage": "UseDevelopmentStorage=true",
e.g.
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "java"
}
}
This is a built-in shortcut for the full connection string to the emulator, which specifies the account name, the account key, and the emulator endpoints for each of the Azure Storage services.
The Azure Storage Explorer opens a tab when you click on a container (named "documents" in our case).
This allows you to upload files manually, which should then hit the breakpoints in the code.
You can stop the code, upload files and restart the code, and the files will still be triggered and hit the breakpoints.
You will likely get this error on running/debugging from IDEA
Failed to start Worker Channel. Process fileName: %JAVA_HOME%/bin/java
You have to go into the run configuration in IDEA and set JAVA_HOME as one of the key pairs.
If you just start the blob service and not the queue service you will get errors like:
An unhandled exception has occurred. Host is shutting down.
Microsoft.WindowsAzure.Storage: Connection refused. System.Net.Http: Connection refused. System.Private.CoreLib: Connection refused.
Make sure both of the services are started.