Blob Storage Integration¶
This recipe covers Java blob processing using trigger, input, and output bindings for ingestion and transformed output patterns.
Architecture¶
flowchart LR
BLOBIN[(incoming container)] --> TRIGGER[@BlobTrigger]
TRIGGER --> TRANSFORM[Transform content]
TRANSFORM --> BLOBOUT[@BlobOutput processed container]
API[HTTP Trigger] --> BLOBREAD[@BlobInput] Prerequisites¶
Create a storage account and containers:
az storage account create \
--name $STORAGE_NAME \
--resource-group $RG \
--location $LOCATION \
--sku Standard_LRS
az storage container create --name incoming --account-name $STORAGE_NAME --auth-mode login
az storage container create --name processed --account-name $STORAGE_NAME --auth-mode login
Configure storage connection:
az functionapp config appsettings set \
--name $APP_NAME \
--resource-group $RG \
--settings "AzureWebJobsStorage=<storage-connection-string>"
Java implementation¶
package com.contoso.functions;
import com.microsoft.azure.functions.*;
import com.microsoft.azure.functions.annotation.*;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
public class BlobFunctions {
@FunctionName("processBlob")
@BlobOutput(
name = "outputBlob",
path = "processed/{name}",
connection = "AzureWebJobsStorage"
)
public byte[] processBlob(
@BlobTrigger(
name = "inputBlob",
path = "incoming/{name}",
connection = "AzureWebJobsStorage"
) byte[] content,
@BindingName("name") String name,
final ExecutionContext context
) {
String transformed = "processed:" + name + ":" + new String(content, StandardCharsets.UTF_8).toUpperCase();
context.getLogger().info("Blob processed: " + name);
return transformed.getBytes(StandardCharsets.UTF_8);
}
@FunctionName("readBlobByApi")
public HttpResponseMessage readBlobByApi(
@HttpTrigger(
name = "request",
methods = {HttpMethod.GET},
authLevel = AuthorizationLevel.FUNCTION,
route = "blobs/{name}"
) HttpRequestMessage<Optional<String>> request,
@BlobInput(
name = "blobContent",
path = "processed/{name}",
connection = "AzureWebJobsStorage"
) String blobContent
) {
if (blobContent == null) {
return request.createResponseBuilder(HttpStatus.NOT_FOUND).body("Blob not found").build();
}
return request.createResponseBuilder(HttpStatus.OK).body(blobContent).build();
}
}
Implementation notes¶
- Keep blob trigger handlers idempotent because retries can happen.
- Use
byte[]for binary-safe processing and convert text explicitly with UTF-8. - Prefer separate containers for raw and processed data.
- For cross-service workflows, emit queue messages after blob processing.